public void selectionChanged(SelectionChangedEvent event) { if (!VrapperPlugin.isVrapperEnabled() || !(event.getSelection() instanceof TextSelection) || selectionService.isSelectionInProgress()) { return; } TextSelection selection = (TextSelection) event.getSelection(); // selection.isEmpty() is false even if length == 0, don't use it if (selection.getLength() == 0) { // Explicitly reset selection. EclipseCursorAndSelection's SelectionChangeListener is // only fired after this listener, returning a stale selection during a mode switch. selectionService.setSelection(null); try { int offset = selection.getOffset(); IRegion lineInfo = textViewer.getDocument().getLineInformationOfOffset(offset); // Checks if cursor is just before line end because Normalmode will move it. if (lineInfo.getOffset() + lineInfo.getLength() == offset) { selectionResetOffset = offset; } else { selectionResetOffset = -1; } } catch (BadLocationException e) { VrapperLog.error("Received bad selection offset in selectionchange handler", e); } EditorMode currentMode = editorAdaptor.getMode(editorAdaptor.getCurrentModeName()); // User cleared selection or moved caret with mouse in a temporary mode. if (currentMode instanceof TemporaryMode) { editorAdaptor.changeModeSafely(InsertMode.NAME); } else if (currentMode instanceof AbstractVisualMode) { editorAdaptor.changeModeSafely(NormalMode.NAME); // Cursor can be after the line if an Eclipse operation cleared the selection, e.g. undo } else if (currentMode instanceof CommandBasedMode) { CommandBasedMode commandMode = (CommandBasedMode) currentMode; commandMode.placeCursor(StickyColumnPolicy.RESET_EOL); } } else if (!VrapperPlugin.isMouseDown() || !editorAdaptor.getConfiguration().get(Options.VISUAL_MOUSE)) { // Mark selection as "conflicted" - we're in Normal mode but somehow a selection exists if (NormalMode.NAME.equals(editorAdaptor.getCurrentModeName())) { editorAdaptor.getCursorService().setCaret(CaretType.UNDERLINE); } return; // Detect if a reverse selection got its last character chopped off. } else if (selectionResetOffset != -1 && (selection.getOffset() + selection.getLength() + 1) == selectionResetOffset) { textViewer.setSelectedRange(selectionResetOffset, -(selection.getLength() + 1)); selectionResetOffset = -1; } else if (selection.getLength() != 0) { if (NormalMode.NAME.equals(editorAdaptor.getCurrentModeName())) { editorAdaptor.changeModeSafely(VisualMode.NAME, AbstractVisualMode.KEEP_SELECTION_HINT); } else if (InsertMode.NAME.equals(editorAdaptor.getCurrentModeName())) { editorAdaptor.changeModeSafely( TempVisualMode.NAME, AbstractVisualMode.KEEP_SELECTION_HINT, InsertMode.DONT_MOVE_CURSOR); } // Store the selection - user might click with mouse and immediately destroy selection editorAdaptor.rememberLastActiveSelection(); } }