private void notifyBatchFoldingProcessingDone(final boolean moveCaretFromCollapsedRegion) { rebuild(); for (FoldingListener listener : myListeners) { listener.onFoldProcessingEnd(); } myEditor.updateCaretCursor(); myEditor.recalculateSizeAndRepaint(); myEditor.getGutterComponentEx().updateSize(); myEditor.getGutterComponentEx().repaint(); for (Caret caret : myEditor.getCaretModel().getAllCarets()) { // There is a possible case that caret position is already visual position aware. But visual // position depends on number of folded // logical lines as well, hence, we can't be sure that target logical position defines correct // visual position because fold // regions have just changed. Hence, we use 'raw' logical position instead. LogicalPosition caretPosition = caret.getLogicalPosition().withoutVisualPositionInfo(); int caretOffset = myEditor.logicalPositionToOffset(caretPosition); int selectionStart = caret.getSelectionStart(); int selectionEnd = caret.getSelectionEnd(); LogicalPosition positionToUse = null; int offsetToUse = -1; FoldRegion collapsed = myFoldTree.fetchOutermost(caretOffset); LogicalPosition savedPosition = caret.getUserData(SAVED_CARET_POSITION); if (savedPosition != null) { int savedOffset = myEditor.logicalPositionToOffset(savedPosition); FoldRegion collapsedAtSaved = myFoldTree.fetchOutermost(savedOffset); if (collapsedAtSaved == null) { positionToUse = savedPosition; } else { offsetToUse = collapsedAtSaved.getStartOffset(); } } if (collapsed != null && positionToUse == null) { positionToUse = myEditor.offsetToLogicalPosition(collapsed.getStartOffset()); } if (moveCaretFromCollapsedRegion && caret.isUpToDate()) { if (offsetToUse >= 0) { caret.moveToOffset(offsetToUse); } else if (positionToUse != null) { caret.moveToLogicalPosition(positionToUse); } else { caret.moveToLogicalPosition(caretPosition); } } caret.putUserData(SAVED_CARET_POSITION, savedPosition); if (isOffsetInsideCollapsedRegion(selectionStart) || isOffsetInsideCollapsedRegion(selectionEnd)) { caret.removeSelection(); } else if (selectionStart < myEditor.getDocument().getTextLength()) { caret.setSelection(selectionStart, selectionEnd); } } if (mySavedCaretShift > 0) { final ScrollingModel scrollingModel = myEditor.getScrollingModel(); scrollingModel.disableAnimation(); scrollingModel.scrollVertically( myEditor.visibleLineToY(myEditor.getCaretModel().getVisualPosition().line) - mySavedCaretShift); scrollingModel.enableAnimation(); } }
private void moveToLogicalPosition(LogicalPosition pos, boolean locateBeforeSoftWrap) { assertIsDispatchThread(); myDesiredX = -1; validateCallContext(); int column = pos.column; int line = pos.line; int softWrapLinesBefore = pos.softWrapLinesBeforeCurrentLogicalLine; int softWrapLinesCurrent = pos.softWrapLinesOnCurrentLogicalLine; int softWrapColumns = pos.softWrapColumnDiff; Document doc = myEditor.getDocument(); if (column < 0) { column = 0; softWrapColumns = 0; } if (line < 0) { line = 0; softWrapLinesBefore = 0; softWrapLinesCurrent = 0; } int lineCount = doc.getLineCount(); if (lineCount == 0) { line = 0; } else if (line > lineCount - 1) { line = lineCount - 1; softWrapLinesBefore = 0; softWrapLinesCurrent = 0; } EditorSettings editorSettings = myEditor.getSettings(); if (!editorSettings.isVirtualSpace() && line < lineCount && !myEditor.getSelectionModel().hasBlockSelection()) { int lineEndOffset = doc.getLineEndOffset(line); int lineEndColumnNumber = myEditor.offsetToLogicalPosition(lineEndOffset).column; if (column > lineEndColumnNumber) { column = lineEndColumnNumber; if (softWrapColumns != 0) { softWrapColumns -= column - lineEndColumnNumber; } } } ((FoldingModelImpl) myEditor.getFoldingModel()).flushCaretPosition(); VerticalInfo oldInfo = myCaretInfo; LogicalPosition oldCaretPosition = myLogicalCaret; LogicalPosition logicalPositionToUse; if (pos.visualPositionAware) { logicalPositionToUse = new LogicalPosition( line, column, softWrapLinesBefore, softWrapLinesCurrent, softWrapColumns, pos.foldedLines, pos.foldingColumnDiff); } else { logicalPositionToUse = new LogicalPosition(line, column); } setCurrentLogicalCaret(logicalPositionToUse); final int offset = myEditor.logicalPositionToOffset(myLogicalCaret); FoldRegion collapsedAt = myEditor.getFoldingModel().getCollapsedRegionAtOffset(offset); if (collapsedAt != null && offset > collapsedAt.getStartOffset()) { Runnable runnable = new Runnable() { public void run() { FoldRegion[] allCollapsedAt = ((FoldingModelImpl) myEditor.getFoldingModel()).fetchCollapsedAt(offset); for (FoldRegion foldRange : allCollapsedAt) { foldRange.setExpanded(true); } } }; myEditor.getFoldingModel().runBatchFoldingOperation(runnable); } myEditor.setLastColumnNumber(myLogicalCaret.column); myVisibleCaret = myEditor.logicalToVisualPosition(myLogicalCaret); myOffset = myEditor.logicalPositionToOffset(myLogicalCaret); LOG.assertTrue(myOffset >= 0 && myOffset <= myEditor.getDocument().getTextLength()); myVisualLineStart = myEditor.logicalPositionToOffset( myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line, 0))); myVisualLineEnd = myEditor.logicalPositionToOffset( myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line + 1, 0))); myEditor.updateCaretCursor(); requestRepaint(oldInfo); if (locateBeforeSoftWrap && SoftWrapHelper.isCaretAfterSoftWrap(myEditor)) { int lineToUse = myVisibleCaret.line - 1; if (lineToUse >= 0) { moveToVisualPosition( new VisualPosition( lineToUse, EditorUtil.getLastVisualLineColumnNumber(myEditor, lineToUse))); return; } } if (!oldCaretPosition.toVisualPosition().equals(myLogicalCaret.toVisualPosition())) { CaretEvent event = new CaretEvent(myEditor, oldCaretPosition, myLogicalCaret); for (CaretListener listener : myCaretListeners) { listener.caretPositionChanged(event); } } }
private void doNotifyBatchFoldingProcessingDone() { myFoldTree.rebuild(); for (FoldingListener listener : myListeners) { listener.onFoldProcessingEnd(); } myEditor.updateCaretCursor(); myEditor.recalculateSizeAndRepaint(); if (myEditor.getGutterComponentEx().isFoldingOutlineShown()) { myEditor.getGutterComponentEx().repaint(); } LogicalPosition caretPosition = myEditor.getCaretModel().getLogicalPosition(); // There is a possible case that caret position is already visual position aware. But visual // position depends on number of folded // logical lines as well, hence, we can't be sure that target logical position defines correct // visual position because fold // regions have just changed. Hence, we use 'raw' logical position instead. if (caretPosition.visualPositionAware) { caretPosition = new LogicalPosition(caretPosition.line, caretPosition.column); } int caretOffset = myEditor.logicalPositionToOffset(caretPosition); boolean hasBlockSelection = myEditor.getSelectionModel().hasBlockSelection(); int selectionStart = myEditor.getSelectionModel().getSelectionStart(); int selectionEnd = myEditor.getSelectionModel().getSelectionEnd(); int column = -1; int line = -1; int offsetToUse = -1; FoldRegion collapsed = myFoldTree.fetchOutermost(caretOffset); if (myCaretPositionSaved) { int savedOffset = myEditor.logicalPositionToOffset(new LogicalPosition(mySavedCaretY, mySavedCaretX)); FoldRegion collapsedAtSaved = myFoldTree.fetchOutermost(savedOffset); if (collapsedAtSaved == null) { column = mySavedCaretX; line = mySavedCaretY; } else { offsetToUse = collapsedAtSaved.getStartOffset(); } } if (collapsed != null && column == -1) { line = collapsed.getDocument().getLineNumber(collapsed.getStartOffset()); column = myEditor.offsetToLogicalPosition(collapsed.getStartOffset()).column; } boolean oldCaretPositionSaved = myCaretPositionSaved; if (offsetToUse >= 0) { myEditor.getCaretModel().moveToOffset(offsetToUse); } else if (column != -1) { myEditor.getCaretModel().moveToLogicalPosition(new LogicalPosition(line, column)); } else { myEditor.getCaretModel().moveToLogicalPosition(caretPosition); } myCaretPositionSaved = oldCaretPositionSaved; if (!hasBlockSelection && selectionStart < myEditor.getDocument().getTextLength()) { myEditor.getSelectionModel().setSelection(selectionStart, selectionEnd); } if (mySavedCaretShift > 0) { myEditor.getScrollingModel().disableAnimation(); int scrollTo = myEditor.visibleLineToY(myEditor.getCaretModel().getVisualPosition().line) - mySavedCaretShift; myEditor.getScrollingModel().scrollVertically(scrollTo); myEditor.getScrollingModel().enableAnimation(); } }
public void moveToVisualPosition(@NotNull VisualPosition pos) { assertIsDispatchThread(); validateCallContext(); myDesiredX = -1; int column = pos.column; int line = pos.line; if (column < 0) column = 0; if (line < 0) line = 0; int lastLine = myEditor.getVisibleLineCount() - 1; if (lastLine <= 0) { lastLine = 0; } if (line > lastLine) { line = lastLine; } EditorSettings editorSettings = myEditor.getSettings(); if (!editorSettings.isVirtualSpace() && line <= lastLine) { int lineEndColumn = EditorUtil.getLastVisualLineColumnNumber(myEditor, line); if (column > lineEndColumn) { column = lineEndColumn; } if (column < 0 && line > 0) { line--; column = EditorUtil.getLastVisualLineColumnNumber(myEditor, line); } } myVisibleCaret = new VisualPosition(line, column); VerticalInfo oldInfo = myCaretInfo; LogicalPosition oldPosition = myLogicalCaret; setCurrentLogicalCaret(myEditor.visualToLogicalPosition(myVisibleCaret)); myOffset = myEditor.logicalPositionToOffset(myLogicalCaret); LOG.assertTrue(myOffset >= 0 && myOffset <= myEditor.getDocument().getTextLength()); myVisualLineStart = myEditor.logicalPositionToOffset( myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line, 0))); myVisualLineEnd = myEditor.logicalPositionToOffset( myEditor.visualToLogicalPosition(new VisualPosition(myVisibleCaret.line + 1, 0))); ((FoldingModelImpl) myEditor.getFoldingModel()).flushCaretPosition(); myEditor.setLastColumnNumber(myVisibleCaret.column); myEditor.updateCaretCursor(); requestRepaint(oldInfo); if (oldPosition.column != myLogicalCaret.column || oldPosition.line != myLogicalCaret.line) { CaretEvent event = new CaretEvent(myEditor, oldPosition, myLogicalCaret); for (CaretListener listener : myCaretListeners) { listener.caretPositionChanged(event); } } }