package org.hunmr.copycutwithoutselection; import com.intellij.codeInsight.highlighting.HighlightManager; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.EditorModificationUtil; import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.editor.markup.HighlighterLayer; import com.intellij.openapi.editor.markup.HighlighterTargetArea; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.util.TextRange; import org.hunmr.common.CommandContext; import org.hunmr.common.EmacsIdeasAction; import org.hunmr.common.selector.Selection; import org.hunmr.common.selector.SelectorFactory; import org.hunmr.util.AppUtil; import org.hunmr.util.ThreadUtil; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; public class CopyCutWithoutSelectAction extends EmacsIdeasAction { private static CopyCutWithoutSelectAction _instance; private KeyListener _handleCopyKeyListener; protected SelectionModel _selection; protected CommandContext _cmdCtx; public CopyCutWithoutSelectAction() { this._instance = this; } public void actionPerformed(AnActionEvent e) { if (super.initAction(e)) { _contentComponent.addKeyListener(_handleCopyKeyListener); } } @Override protected void initMemberVariableForConvenientAccess(AnActionEvent e) { super.initMemberVariableForConvenientAccess(e); _handleCopyKeyListener = createHandleCopyWithoutSelectionKeyListener(); _selection = _editor.getSelectionModel(); _cmdCtx = new CommandContext(); } private KeyListener createHandleCopyWithoutSelectionKeyListener() { return new KeyListener() { public void keyTyped(KeyEvent keyEvent) { keyEvent.consume(); boolean copyFinished = handleKey(keyEvent.getKeyChar()); if (copyFinished) { cleanupSetupsInAndBackToNormalEditingMode(); handlePendingActionOnSuccess(); } } public void keyPressed(KeyEvent keyEvent) { if (KeyEvent.VK_ESCAPE == keyEvent.getKeyChar()) { cleanupSetupsInAndBackToNormalEditingMode(); } } public void keyReleased(KeyEvent keyEvent) { } }; } protected boolean handleKey(char key) { if (_cmdCtx.consume(key)) { return false; } if (SelectorFactory.isSelectorKey(key)) { final TextRange tr = Selection.getTextRangeBy(_editor, _cmdCtx); if (tr != null) { _selection.setSelection(tr.getStartOffset(), tr.getEndOffset()); doActionOnSelectedRange(tr); } return true; } return true; } private void doActionOnSelectedRange(TextRange tr) { if (_cmdCtx.getPrefixCount() == 0) { copySelection(tr); } else if (_cmdCtx.getPrefixCount() == 1) { cutSelection(); } } private void cutSelection() { Runnable cutRunnable = new Runnable() { @Override public void run() { _editor.getSelectionModel().copySelectionToClipboard(); EditorModificationUtil.deleteSelectedText(_editor); } }; AppUtil.runWriteAction(cutRunnable, _editor); } private void copySelection(TextRange tr) { _selection.copySelectionToClipboard(); _selection.removeSelection(); final RangeHighlighter rh = addHighlighterOnCopiedRange(tr); ApplicationManager.getApplication().invokeLater(createClearHighlighterRunnable(rh)); } private Runnable createClearHighlighterRunnable(final RangeHighlighter rh) { return new Runnable() { @Override public void run() { ThreadUtil.sleep(200); _editor.getMarkupModel().removeHighlighter(rh); } }; } private RangeHighlighter addHighlighterOnCopiedRange(TextRange tr) { TextAttributes textAttributes = new TextAttributes(); textAttributes.setBackgroundColor(SelectorFactory.HIGHLIGHT_COLOR); return _editor.getMarkupModel().addRangeHighlighter(tr.getStartOffset(), tr.getEndOffset(), HighlighterLayer.LAST + 1, textAttributes, HighlighterTargetArea.EXACT_RANGE); } public void cleanupSetupsInAndBackToNormalEditingMode() { if (_handleCopyKeyListener != null) { _contentComponent.removeKeyListener(_handleCopyKeyListener); _handleCopyKeyListener = null; } super.cleanupSetupsInAndBackToNormalEditingMode(); } public static CopyCutWithoutSelectAction getInstance() { if (_instance == null) { _instance = new CopyCutWithoutSelectAction(); } return _instance; } public CommandContext getCmdContext() { return _instance._cmdCtx; } }