public void collapseFoldRegion(FoldRegion region) { assertIsDispatchThread(); if (!region.isExpanded()) return; if (!myIsBatchFoldingProcessing) { LOG.error("Fold regions must be collapsed or expanded inside batchFoldProcessing() only."); } LogicalPosition caretPosition = myEditor.getCaretModel().getLogicalPosition(); int caretOffset = myEditor.logicalPositionToOffset(caretPosition); if (FoldRegionsTree.contains(region, caretOffset)) { if (myDoNotCollapseCaret) return; if (!myCaretPositionSaved) { mySavedCaretX = caretPosition.column; mySavedCaretY = caretPosition.line; myCaretPositionSaved = true; } } int selectionStart = myEditor.getSelectionModel().getSelectionStart(); int selectionEnd = myEditor.getSelectionModel().getSelectionEnd(); if (FoldRegionsTree.contains(region, selectionStart - 1) || FoldRegionsTree.contains(region, selectionEnd)) myEditor.getSelectionModel().removeSelection(); myFoldRegionsProcessed = true; ((FoldRegionImpl) region).setExpandedInternal(false); notifyListenersOnFoldRegionStateChange(region); }
public void collapseFoldRegion(FoldRegion region) { assertIsDispatchThreadForEditor(); if (!region.isExpanded()) return; if (!myIsBatchFoldingProcessing) { LOG.error("Fold regions must be collapsed or expanded inside batchFoldProcessing() only."); } List<Caret> carets = myEditor.getCaretModel().getAllCarets(); for (Caret caret : carets) { LogicalPosition caretPosition = caret.getLogicalPosition(); int caretOffset = myEditor.logicalPositionToOffset(caretPosition); if (FoldRegionsTree.contains(region, caretOffset)) { if (myDoNotCollapseCaret) return; } } for (Caret caret : carets) { LogicalPosition caretPosition = caret.getLogicalPosition(); int caretOffset = myEditor.logicalPositionToOffset(caretPosition); if (FoldRegionsTree.contains(region, caretOffset)) { if (caret.getUserData(SAVED_CARET_POSITION) == null) { caret.putUserData(SAVED_CARET_POSITION, caretPosition.withoutVisualPositionInfo()); } } } myFoldRegionsProcessed = true; ((FoldRegionImpl) region).setExpandedInternal(false); notifyListenersOnFoldRegionStateChange(region); }
private void runBatchFoldingOperation( final Runnable operation, final boolean dontCollapseCaret, final boolean moveCaret) { assertIsDispatchThreadForEditor(); boolean oldDontCollapseCaret = myDoNotCollapseCaret; myDoNotCollapseCaret |= dontCollapseCaret; boolean oldBatchFlag = myIsBatchFoldingProcessing; if (!oldBatchFlag) { ((ScrollingModelImpl) myEditor.getScrollingModel()).finishAnimation(); mySavedCaretShift = myEditor.visibleLineToY(myEditor.getCaretModel().getVisualPosition().line) - myEditor.getScrollingModel().getVerticalScrollOffset(); } myIsBatchFoldingProcessing = true; try { operation.run(); } finally { if (!oldBatchFlag) { if (myFoldRegionsProcessed) { notifyBatchFoldingProcessingDone(moveCaret); myFoldRegionsProcessed = false; } myIsBatchFoldingProcessing = false; } myDoNotCollapseCaret = oldDontCollapseCaret; } }
private void runBatchFoldingOperation(final Runnable operation, final boolean dontCollapseCaret) { assertIsDispatchThread(); boolean oldDontCollapseCaret = myDoNotCollapseCaret; myDoNotCollapseCaret |= dontCollapseCaret; boolean oldBatchFlag = myIsBatchFoldingProcessing; if (!oldBatchFlag) { mySavedCaretShift = myEditor.visibleLineToY(myEditor.getCaretModel().getVisualPosition().line) - myEditor.getScrollingModel().getVerticalScrollOffset(); } myIsBatchFoldingProcessing = true; myFoldTree.myCachedLastIndex = -1; operation.run(); myFoldTree.myCachedLastIndex = -1; if (!oldBatchFlag) { if (myFoldRegionsProcessed) { notifyBatchFoldingProcessingDone(); myFoldRegionsProcessed = false; } myIsBatchFoldingProcessing = false; } myDoNotCollapseCaret = oldDontCollapseCaret; }
public void doClick(final MouseEvent e, final int width) { RangeHighlighter marker = getNearestRangeHighlighter(e, width); if (marker == null) return; int offset = marker.getStartOffset(); final Document doc = myEditor.getDocument(); if (doc.getLineCount() > 0) { // Necessary to expand folded block even if navigating just before one // Very useful when navigating to first unused import statement. int lineEnd = doc.getLineEndOffset(doc.getLineNumber(offset)); myEditor.getCaretModel().moveToOffset(lineEnd); } myEditor.getCaretModel().moveToOffset(offset); myEditor.getSelectionModel().removeSelection(); ScrollingModel scrollingModel = myEditor.getScrollingModel(); scrollingModel.disableAnimation(); scrollingModel.scrollToCaret(ScrollType.CENTER); scrollingModel.enableAnimation(); fireErrorMarkerClicked(marker, e); }
@Override public int paint( @NotNull Graphics g, @NotNull SoftWrapDrawingType drawingType, int x, int y, int lineHeight) { if (!isSoftWrappingEnabled()) { return 0; } if (!myEditor.getSettings().isAllSoftWrapsShown()) { int visualLine = y / lineHeight; LogicalPosition position = myEditor.visualToLogicalPosition(new VisualPosition(visualLine, 0)); if (position.line != myEditor.getCaretModel().getLogicalPosition().line) { return myPainter.getDrawingHorizontalOffset(g, drawingType, x, y, lineHeight); } } return doPaint(g, drawingType, x, y, lineHeight); }
private Map<Integer, Couple<Integer>> createVirtualSelectionMap( int startVisualLine, int endVisualLine) { HashMap<Integer, Couple<Integer>> map = new HashMap<Integer, Couple<Integer>>(); for (Caret caret : myEditor.getCaretModel().getAllCarets()) { if (caret.hasSelection()) { VisualPosition selectionStart = caret.getSelectionStartPosition(); VisualPosition selectionEnd = caret.getSelectionEndPosition(); if (selectionStart.line == selectionEnd.line) { int line = selectionStart.line; if (line >= startVisualLine && line <= endVisualLine) { map.put(line, Couple.of(selectionStart.column, selectionEnd.column)); } } } } return map; }
@Override public void beforeDocumentChangeAtCaret() { CaretModel caretModel = myEditor.getCaretModel(); VisualPosition visualCaretPosition = caretModel.getVisualPosition(); if (!isInsideSoftWrap(visualCaretPosition)) { return; } SoftWrap softWrap = myStorage.getSoftWrap(caretModel.getOffset()); if (softWrap == null) { return; } myEditor .getDocument() .replaceString(softWrap.getStart(), softWrap.getEnd(), softWrap.getText()); caretModel.moveToVisualPosition(visualCaretPosition); }
public void expandFoldRegion(FoldRegion region) { assertIsDispatchThread(); if (region.isExpanded() || region.shouldNeverExpand()) return; if (!myIsBatchFoldingProcessing) { LOG.error("Fold regions must be collapsed or expanded inside batchFoldProcessing() only."); } if (myCaretPositionSaved) { int savedOffset = myEditor.logicalPositionToOffset(new LogicalPosition(mySavedCaretY, mySavedCaretX)); FoldRegion[] allCollapsed = myFoldTree.fetchCollapsedAt(savedOffset); if (allCollapsed.length == 1 && allCollapsed[0] == region) { LogicalPosition pos = new LogicalPosition(mySavedCaretY, mySavedCaretX); myEditor.getCaretModel().moveToLogicalPosition(pos); } } myFoldRegionsProcessed = true; ((FoldRegionImpl) region).setExpandedInternal(true); notifyListenersOnFoldRegionStateChange(region); }
public void expandFoldRegion(FoldRegion region) { assertIsDispatchThreadForEditor(); if (region.isExpanded() || region.shouldNeverExpand()) return; if (!myIsBatchFoldingProcessing) { LOG.error("Fold regions must be collapsed or expanded inside batchFoldProcessing() only."); } for (Caret caret : myEditor.getCaretModel().getAllCarets()) { LogicalPosition savedPosition = caret.getUserData(SAVED_CARET_POSITION); if (savedPosition != null) { int savedOffset = myEditor.logicalPositionToOffset(savedPosition); FoldRegion[] allCollapsed = myFoldTree.fetchCollapsedAt(savedOffset); if (allCollapsed.length == 1 && allCollapsed[0] == region) { caret.moveToLogicalPosition(savedPosition); } } } myFoldRegionsProcessed = true; ((FoldRegionImpl) region).setExpandedInternal(true); notifyListenersOnFoldRegionStateChange(region); }
public void flushCaretPosition() { for (Caret caret : myEditor.getCaretModel().getAllCarets()) { caret.putUserData(SAVED_CARET_POSITION, null); } }
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 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(); } }