Search in sources :

Example 1 with CaretEvent

use of com.intellij.openapi.editor.event.CaretEvent in project intellij-community by JetBrains.

the class CaretImpl method moveToOffset.

@Override
public void moveToOffset(final int offset, final boolean locateBeforeSoftWrap) {
    assertIsDispatchThread();
    validateCallContext();
    if (mySkipChangeRequests) {
        return;
    }
    myEditor.getCaretModel().doWithCaretMerging(() -> {
        final LogicalPosition logicalPosition = myEditor.offsetToLogicalPosition(offset);
        CaretEvent event = moveToLogicalPosition(logicalPosition, locateBeforeSoftWrap, null, false);
        final LogicalPosition positionByOffsetAfterMove = myEditor.offsetToLogicalPosition(getOffset());
        if (!positionByOffsetAfterMove.equals(logicalPosition)) {
            StringBuilder debugBuffer = new StringBuilder();
            moveToLogicalPosition(logicalPosition, locateBeforeSoftWrap, debugBuffer, true);
            int actualOffset = getOffset();
            int textStart = Math.max(0, Math.min(offset, actualOffset) - 1);
            final DocumentEx document = myEditor.getDocument();
            int textEnd = Math.min(document.getTextLength() - 1, Math.max(offset, actualOffset) + 1);
            CharSequence text = document.getCharsSequence().subSequence(textStart, textEnd);
            int inverseOffset = myEditor.logicalPositionToOffset(logicalPosition);
            LogMessageEx.error(LOG, "caret moved to wrong offset. Please submit a dedicated ticket and attach current editor's text to it.", "Requested: offset=" + offset + ", logical position='" + logicalPosition + "' but actual: offset=" + actualOffset + ", logical position='" + myLogicalCaret + "' (" + positionByOffsetAfterMove + "). " + myEditor.dumpState() + "\ninterested text [" + textStart + ";" + textEnd + "): '" + text + "'\n debug trace: " + debugBuffer + "\nLogical position -> offset ('" + logicalPosition + "'->'" + inverseOffset + "')");
        }
        if (event != null) {
            myEditor.getCaretModel().fireCaretPositionChanged(event);
            EditorActionUtil.selectNonexpandableFold(myEditor);
        }
    });
}
Also used : CaretEvent(com.intellij.openapi.editor.event.CaretEvent) DocumentEx(com.intellij.openapi.editor.ex.DocumentEx)

Example 2 with CaretEvent

use of com.intellij.openapi.editor.event.CaretEvent in project intellij-community by JetBrains.

the class FindUtil method processNotFound.

public static void processNotFound(final Editor editor, String stringToFind, FindModel model, Project project) {
    String message = FindBundle.message("find.search.string.not.found.message", stringToFind);
    short position = HintManager.UNDER;
    if (model.isGlobal()) {
        final FindModel newModel = model.clone();
        FindManager findManager = FindManager.getInstance(project);
        Document document = editor.getDocument();
        FindResult result = findManager.findString(document.getCharsSequence(), newModel.isForward() ? 0 : document.getTextLength(), model, getVirtualFile(editor));
        if (!result.isStringFound()) {
            result = null;
        }
        FindModel modelForNextSearch = findManager.getFindNextModel(editor);
        if (modelForNextSearch == null) {
            modelForNextSearch = findManager.getFindInFileModel();
        }
        if (result != null) {
            if (newModel.isForward()) {
                AnAction action = ActionManager.getInstance().getAction(modelForNextSearch.isForward() ? IdeActions.ACTION_FIND_NEXT : IdeActions.ACTION_FIND_PREVIOUS);
                String shortcutsText = KeymapUtil.getFirstKeyboardShortcutText(action);
                if (!shortcutsText.isEmpty()) {
                    message = FindBundle.message("find.search.again.from.top.hotkey.message", message, shortcutsText);
                } else {
                    message = FindBundle.message("find.search.again.from.top.action.message", message);
                }
                editor.putUserData(KEY, Direction.DOWN);
            } else {
                AnAction action = ActionManager.getInstance().getAction(modelForNextSearch.isForward() ? IdeActions.ACTION_FIND_PREVIOUS : IdeActions.ACTION_FIND_NEXT);
                String shortcutsText = KeymapUtil.getFirstKeyboardShortcutText(action);
                if (!shortcutsText.isEmpty()) {
                    message = FindBundle.message("find.search.again.from.bottom.hotkey.message", message, shortcutsText);
                } else {
                    message = FindBundle.message("find.search.again.from.bottom.action.message", message);
                }
                editor.putUserData(KEY, Direction.UP);
                position = HintManager.ABOVE;
            }
        }
        CaretListener listener = new CaretAdapter() {

            @Override
            public void caretPositionChanged(CaretEvent e) {
                editor.putUserData(KEY, null);
                editor.getCaretModel().removeCaretListener(this);
            }
        };
        editor.getCaretModel().addCaretListener(listener);
    }
    JComponent component = HintUtil.createInformationLabel(JDOMUtil.escapeText(message, false, false));
    final LightweightHint hint = new LightweightHint(component);
    HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, position, HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING, 0, false);
}
Also used : CaretEvent(com.intellij.openapi.editor.event.CaretEvent) CaretListener(com.intellij.openapi.editor.event.CaretListener) LightweightHint(com.intellij.ui.LightweightHint) CaretAdapter(com.intellij.openapi.editor.event.CaretAdapter)

Example 3 with CaretEvent

use of com.intellij.openapi.editor.event.CaretEvent in project intellij-community by JetBrains.

the class CaretModelWindow method addCaretListener.

@Override
public void addCaretListener(@NotNull final CaretListener listener) {
    CaretListener wrapper = new CaretAdapter() {

        @Override
        public void caretPositionChanged(CaretEvent e) {
            // injected document can be destroyed by now
            if (!myEditorWindow.getDocument().isValid())
                return;
            CaretEvent event = new CaretEvent(myEditorWindow, createInjectedCaret(e.getCaret()), myEditorWindow.hostToInjected(e.getOldPosition()), myEditorWindow.hostToInjected(e.getNewPosition()));
            listener.caretPositionChanged(event);
        }
    };
    myCaretListeners.registerWrapper(listener, wrapper);
    myDelegate.addCaretListener(wrapper);
}
Also used : CaretEvent(com.intellij.openapi.editor.event.CaretEvent) CaretListener(com.intellij.openapi.editor.event.CaretListener) CaretAdapter(com.intellij.openapi.editor.event.CaretAdapter)

Example 4 with CaretEvent

use of com.intellij.openapi.editor.event.CaretEvent in project intellij-community by JetBrains.

the class CaretImpl method doMoveToLogicalPosition.

private CaretEvent doMoveToLogicalPosition(@NotNull LogicalPosition pos, boolean locateBeforeSoftWrap, @NonNls @Nullable StringBuilder debugBuffer, boolean fireListeners) {
    assertIsDispatchThread();
    updateCachedStateIfNeeded();
    if (debugBuffer != null) {
        debugBuffer.append("Start moveToLogicalPosition(). Locate before soft wrap: ").append(locateBeforeSoftWrap).append(", position: ").append(pos).append("\n");
    }
    myDesiredX = -1;
    validateCallContext();
    int column = pos.column;
    int line = pos.line;
    int softWrapLinesBefore = pos.softWrapLinesBeforeCurrentLogicalLine;
    int softWrapLinesCurrent = pos.softWrapLinesOnCurrentLogicalLine;
    int softWrapColumns = pos.softWrapColumnDiff;
    boolean leansForward = pos.leansForward;
    boolean leansRight = pos.visualPositionLeansRight;
    Document doc = myEditor.getDocument();
    int lineCount = doc.getLineCount();
    if (lineCount == 0) {
        if (debugBuffer != null) {
            debugBuffer.append("Resetting target logical line to zero as the document is empty\n");
        }
        line = 0;
    } else if (line > lineCount - 1) {
        if (debugBuffer != null) {
            debugBuffer.append("Resetting target logical line (").append(line).append(") to ").append(lineCount - 1).append(" as it is greater than total document lines number\n");
        }
        line = lineCount - 1;
        softWrapLinesBefore = 0;
        softWrapLinesCurrent = 0;
    }
    EditorSettings editorSettings = myEditor.getSettings();
    if (!editorSettings.isVirtualSpace() && line < lineCount) {
        int lineEndOffset = doc.getLineEndOffset(line);
        final LogicalPosition endLinePosition = myEditor.offsetToLogicalPosition(lineEndOffset);
        int lineEndColumnNumber = endLinePosition.column;
        if (column > lineEndColumnNumber) {
            int oldColumn = column;
            column = lineEndColumnNumber;
            leansForward = true;
            leansRight = true;
            if (softWrapColumns != 0) {
                softWrapColumns -= column - lineEndColumnNumber;
            }
            if (debugBuffer != null) {
                debugBuffer.append("Resetting target logical column (").append(oldColumn).append(") to ").append(lineEndColumnNumber).append(" because caret is not allowed to be located after line end (offset: ").append(lineEndOffset).append(", ").append("logical position: ").append(endLinePosition).append("). Current soft wrap columns value: ").append(softWrapColumns).append("\n");
            }
        }
    }
    myEditor.getFoldingModel().flushCaretPosition(this);
    VerticalInfo oldInfo = myCaretInfo;
    LogicalPosition oldCaretPosition = myLogicalCaret;
    VisualPosition oldVisualPosition = myVisibleCaret;
    LogicalPosition logicalPositionToUse;
    if (pos.visualPositionAware) {
        logicalPositionToUse = new LogicalPosition(line, column, softWrapLinesBefore, softWrapLinesCurrent, softWrapColumns, pos.foldedLines, pos.foldingColumnDiff, leansForward, leansRight);
    } else {
        logicalPositionToUse = new LogicalPosition(line, column, leansForward);
    }
    final int offset = myEditor.logicalPositionToOffset(logicalPositionToUse);
    if (debugBuffer != null) {
        debugBuffer.append("Resulting logical position to use: ").append(logicalPositionToUse).append(". It's mapped to offset ").append(offset).append("\n");
    }
    FoldRegion collapsedAt = myEditor.getFoldingModel().getCollapsedRegionAtOffset(offset);
    if (collapsedAt != null && offset > collapsedAt.getStartOffset()) {
        if (debugBuffer != null) {
            debugBuffer.append("Scheduling expansion of fold region ").append(collapsedAt).append("\n");
        }
        Runnable runnable = () -> {
            FoldRegion[] allCollapsedAt = myEditor.getFoldingModel().fetchCollapsedAt(offset);
            for (FoldRegion foldRange : allCollapsedAt) {
                foldRange.setExpanded(true);
            }
        };
        mySkipChangeRequests = true;
        try {
            myEditor.getFoldingModel().runBatchFoldingOperation(runnable, false);
        } finally {
            mySkipChangeRequests = false;
        }
        logicalPositionToUse = logicalPositionToUse.visualPositionAware ? logicalPositionToUse.withoutVisualPositionInfo() : logicalPositionToUse;
    }
    setCurrentLogicalCaret(logicalPositionToUse);
    setLastColumnNumber(myLogicalCaret.column);
    myDesiredSelectionStartColumn = myDesiredSelectionEndColumn = -1;
    myVisibleCaret = myEditor.logicalToVisualPosition(myLogicalCaret);
    updateOffsetsFromLogicalPosition();
    int newOffset = getOffset();
    if (debugBuffer != null) {
        debugBuffer.append("Storing offset ").append(newOffset).append(" (mapped from logical position ").append(myLogicalCaret).append(")\n");
    }
    updateVisualLineInfo();
    myEditor.updateCaretCursor();
    requestRepaint(oldInfo);
    if (locateBeforeSoftWrap && SoftWrapHelper.isCaretAfterSoftWrap(this)) {
        int lineToUse = myVisibleCaret.line - 1;
        if (lineToUse >= 0) {
            final VisualPosition visualPosition = new VisualPosition(lineToUse, EditorUtil.getLastVisualLineColumnNumber(myEditor, lineToUse));
            if (debugBuffer != null) {
                debugBuffer.append("Adjusting caret position by moving it before soft wrap. Moving to visual position ").append(visualPosition).append("\n");
            }
            final LogicalPosition logicalPosition = myEditor.visualToLogicalPosition(visualPosition);
            final int tmpOffset = myEditor.logicalPositionToOffset(logicalPosition);
            if (tmpOffset == newOffset) {
                boolean restore = myReportCaretMoves;
                myReportCaretMoves = false;
                try {
                    moveToVisualPosition(visualPosition);
                    return null;
                } finally {
                    myReportCaretMoves = restore;
                }
            } else {
                LogMessageEx.error(LOG, "Invalid editor dimension mapping", "Expected to map visual position '" + visualPosition + "' to offset " + newOffset + " but got the following: -> logical position '" + logicalPosition + "'; -> offset " + tmpOffset + ". State: " + myEditor.dumpState());
            }
        }
    }
    if (!oldVisualPosition.equals(myVisibleCaret)) {
        CaretEvent event = new CaretEvent(myEditor, this, oldCaretPosition, myLogicalCaret);
        if (fireListeners) {
            myEditor.getCaretModel().fireCaretPositionChanged(event);
        } else {
            return event;
        }
    }
    return null;
}
Also used : CaretEvent(com.intellij.openapi.editor.event.CaretEvent)

Example 5 with CaretEvent

use of com.intellij.openapi.editor.event.CaretEvent in project intellij-community by JetBrains.

the class CaretImpl method moveToVisualPosition.

void moveToVisualPosition(@NotNull VisualPosition pos, boolean fireListeners) {
    assertIsDispatchThread();
    validateCallContext();
    if (mySkipChangeRequests) {
        return;
    }
    if (myReportCaretMoves) {
        LogMessageEx.error(LOG, "Unexpected caret move request");
    }
    if (!myEditor.isStickySelection() && !myEditor.getDocument().isInEventsHandling() && !pos.equals(myVisibleCaret)) {
        CopyPasteManager.getInstance().stopKillRings();
    }
    updateCachedStateIfNeeded();
    myDesiredX = -1;
    int column = pos.column;
    int line = pos.line;
    boolean leanRight = pos.leansRight;
    int lastLine = myEditor.getVisibleLineCount() - 1;
    if (lastLine <= 0) {
        lastLine = 0;
    }
    if (line > lastLine) {
        line = lastLine;
    }
    EditorSettings editorSettings = myEditor.getSettings();
    if (!editorSettings.isVirtualSpace()) {
        int lineEndColumn = EditorUtil.getLastVisualLineColumnNumber(myEditor, line);
        if (column > lineEndColumn && !myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) {
            column = lineEndColumn;
            leanRight = true;
        }
    }
    myVisibleCaret = new VisualPosition(line, column, leanRight);
    VerticalInfo oldInfo = myCaretInfo;
    LogicalPosition oldPosition = myLogicalCaret;
    setCurrentLogicalCaret(myEditor.visualToLogicalPosition(myVisibleCaret));
    updateOffsetsFromLogicalPosition();
    updateVisualLineInfo();
    myEditor.getFoldingModel().flushCaretPosition(this);
    setLastColumnNumber(myLogicalCaret.column);
    myDesiredSelectionStartColumn = myDesiredSelectionEndColumn = -1;
    myEditor.updateCaretCursor();
    requestRepaint(oldInfo);
    if (fireListeners && !oldPosition.equals(myLogicalCaret)) {
        CaretEvent event = new CaretEvent(myEditor, this, oldPosition, myLogicalCaret);
        myEditor.getCaretModel().fireCaretPositionChanged(event);
    }
}
Also used : CaretEvent(com.intellij.openapi.editor.event.CaretEvent)

Aggregations

CaretEvent (com.intellij.openapi.editor.event.CaretEvent)6 CaretAdapter (com.intellij.openapi.editor.event.CaretAdapter)3 CaretListener (com.intellij.openapi.editor.event.CaretListener)2 DocumentAdapter (com.intellij.openapi.editor.event.DocumentAdapter)1 DocumentEvent (com.intellij.openapi.editor.event.DocumentEvent)1 DocumentEx (com.intellij.openapi.editor.ex.DocumentEx)1 LightweightHint (com.intellij.ui.LightweightHint)1