void (@NotNull ActionEvent e) { myCommandProcessor.executeCommand(myProject, new DocumentRunnable(myDocument, myProject) { @Override public void run() { // We experienced situation when particular editor was disposed but the timer was still on. if (isDisposed()) { myTimer.stop(); return; } int oldSelectionStart = mySelectionModel.getLeadSelectionOffset(); VisualPosition caretPosition = myMultiSelectionInProgress ? myTargetMultiSelectionPosition : getCaretModel().getVisualPosition(); int column = caretPosition.column; xPassedCycles++; if (xPassedCycles >= myXCycles) { xPassedCycles = 0; column += myDx; } int line = caretPosition.line; yPassedCycles++; if (yPassedCycles >= myYCycles) { yPassedCycles = 0; line += myDy; } line = Math.max(0, line); column = Math.max(0, column); VisualPosition pos = new VisualPosition(line, column); if (!myMultiSelectionInProgress) { getCaretModel().moveToVisualPosition(pos); getScrollingModel().scrollToCaret(ScrollType.RELATIVE); } int newCaretOffset = getCaretModel().getOffset(); int caretShift = newCaretOffset - mySavedSelectionStart; if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) { if (caretShift < 0) { int newSelection = newCaretOffset; if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { newSelection = myCaretModel.getWordAtCaretStart(); } else { if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { newSelection = logicalPositionToOffset(visualToLogicalPosition(new VisualPosition(getCaretModel().getVisualPosition().line, 0))); } } if (newSelection < 0) newSelection = newCaretOffset; mySelectionModel.setSelection(validateOffset(mySavedSelectionEnd), newSelection); getCaretModel().moveToOffset(newSelection); } else { int newSelection = newCaretOffset; if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { newSelection = myCaretModel.getWordAtCaretEnd(); } else { if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { newSelection = logicalPositionToOffset( visualToLogicalPosition(new VisualPosition(getCaretModel().getVisualPosition().line + 1, 0))); } } if (newSelection < 0) newSelection = newCaretOffset; mySelectionModel.setSelection(validateOffset(mySavedSelectionStart), newSelection); getCaretModel().moveToOffset(newSelection); } return; } if (myMultiSelectionInProgress && myLastMousePressedLocation != null) { myTargetMultiSelectionPosition = pos; LogicalPosition newLogicalPosition = visualToLogicalPosition(pos); getScrollingModel().scrollTo(newLogicalPosition, ScrollType.RELATIVE); createSelectionTill(newLogicalPosition); } else { mySelectionModel.setSelection(oldSelectionStart, getCaretModel().getOffset()); } } }, EditorBundle.message("move.cursor.command.name"), DocCommandGroupId.noneGroupId(getDocument()), UndoConfirmationPolicy.DEFAULT, getDocument()); }