Java Code Examples for com.intellij.openapi.editor.event.DocumentEvent#getNewLength()

The following examples show how to use com.intellij.openapi.editor.event.DocumentEvent#getNewLength() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: LanguageConsoleBuilder.java    From consulo with Apache License 2.0 6 votes vote down vote up
@Override
public void documentChanged(DocumentEvent event) {
  DocumentEx document = getDocument();
  if (document.isInBulkUpdate()) {
    return;
  }

  if (document.getTextLength() > 0) {
    addLineSeparatorPainterIfNeed();
    int startDocLine = document.getLineNumber(event.getOffset());
    int endDocLine = document.getLineNumber(event.getOffset() + event.getNewLength());
    if (event.getOldLength() > event.getNewLength() || startDocLine != endDocLine || StringUtil.indexOf(event.getOldFragment(), '\n') != -1) {
      updateGutterSize(startDocLine, endDocLine);
    }
  }
  else if (event.getOldLength() > 0) {
    documentCleared();
  }
}
 
Example 2
Source File: LineStatusTrackerBase.java    From consulo with Apache License 2.0 6 votes vote down vote up
@Nonnull
private int[] fixRanges(@Nonnull DocumentEvent e, int line1, int line2) {
  CharSequence document = myDocument.getCharsSequence();
  int offset = e.getOffset();

  if (e.getOldLength() == 0 && e.getNewLength() != 0) {
    if (StringUtil.endsWithChar(e.getNewFragment(), '\n') && isNewline(offset - 1, document)) {
      return new int[]{line1, line2 - 1};
    }
    if (StringUtil.startsWithChar(e.getNewFragment(), '\n') && isNewline(offset + e.getNewLength(), document)) {
      return new int[]{line1 + 1, line2};
    }
  }
  if (e.getOldLength() != 0 && e.getNewLength() == 0) {
    if (StringUtil.endsWithChar(e.getOldFragment(), '\n') && isNewline(offset - 1, document)) {
      return new int[]{line1, line2 - 1};
    }
    if (StringUtil.startsWithChar(e.getOldFragment(), '\n') && isNewline(offset + e.getNewLength(), document)) {
      return new int[]{line1 + 1, line2};
    }
  }

  return new int[]{line1, line2};
}
 
Example 3
Source File: RangeMarkerImpl.java    From consulo with Apache License 2.0 6 votes vote down vote up
@Nullable
private static TextRange processIfOnePoint(@Nonnull DocumentEvent e, int intervalStart, boolean greedyRight, boolean stickyRight) {
  int offset = e.getOffset();
  int oldLength = e.getOldLength();
  int oldEnd = offset + oldLength;
  if (offset < intervalStart && intervalStart < oldEnd) {
    return null;
  }

  if (offset == intervalStart && oldLength == 0) {
    if (greedyRight) {
      return new UnfairTextRange(intervalStart, intervalStart + e.getNewLength());
    }
    else if (stickyRight) {
      return new UnfairTextRange(intervalStart + e.getNewLength(), intervalStart + e.getNewLength());
    }
  }

  if (intervalStart > oldEnd || intervalStart == oldEnd && oldLength > 0) {
    return new UnfairTextRange(intervalStart + e.getNewLength() - oldLength, intervalStart + e.getNewLength() - oldLength);
  }

  return new UnfairTextRange(intervalStart, intervalStart);
}
 
Example 4
Source File: RangeMarkerImpl.java    From consulo with Apache License 2.0 6 votes vote down vote up
@Override
public final void documentChanged(@Nonnull DocumentEvent e) {
  int oldStart = intervalStart();
  int oldEnd = intervalEnd();
  int docLength = getDocument().getTextLength();
  if (!isValid()) {
    LOG.error("Invalid range marker " + (isGreedyToLeft() ? "[" : "(") + oldStart + ", " + oldEnd + (isGreedyToRight() ? "]" : ")") +
              ". Event = " + e + ". Doc length=" + docLength + "; " + getClass());
    return;
  }
  if (intervalStart() > intervalEnd() || intervalStart() < 0 || intervalEnd() > docLength - e.getNewLength() + e.getOldLength()) {
    LOG.error("RangeMarker" + (isGreedyToLeft() ? "[" : "(") + oldStart + ", " + oldEnd + (isGreedyToRight() ? "]" : ")") +
              " is invalid before update. Event = " + e + ". Doc length=" + docLength + "; " + getClass());
    invalidate(e);
    return;
  }
  changedUpdateImpl(e);
  if (isValid() && (intervalStart() > intervalEnd() || intervalStart() < 0 || intervalEnd() > docLength)) {
    LOG.error("Update failed. Event = " + e + ". " +
              "old doc length=" + docLength + "; real doc length = " + getDocument().getTextLength() +
              "; " + getClass() + "." +
              " After update: '" + this + "'");
    invalidate(e);
  }
}
 
Example 5
Source File: LineOrientedDocumentChangeAdapter.java    From consulo with Apache License 2.0 5 votes vote down vote up
@Override
public void beforeDocumentChange(DocumentEvent event) {
  Document document = event.getDocument();
  int startLine = document.getLineNumber(normalize(event.getDocument(), event.getOffset()));
  int endLine = document.getLineNumber(normalize(event.getDocument(), event.getOffset() + event.getOldLength()));
  int symbolsDifference = event.getNewLength() - event.getOldLength();
  beforeDocumentChange(startLine, endLine, symbolsDifference);
}
 
Example 6
Source File: DocumentChangesCollector.java    From consulo with Apache License 2.0 5 votes vote down vote up
/**
 * Updates current object's state on the basis of the given event assuming that there are no stored change ranges that
 * start after offset denoted by the given event.
 *
 * @param event     event for just occurred document change
 * @param oldText   our main idea is to merge all changes in order to have aggregated change against original document. So, there is
 *                  a possible case that subsequent change affects text inserted by the previous one. We don't want to reflect that
 *                  at aggregated change as it didn't appear in initial document. Hence, we have a mutable symbols buffer that holds
 *                  symbols from initial document affected by the given change
 */
private void updateChanges(DocumentEvent event, StringBuilder oldText) {
  int i = findIndex(event.getOffset());
  int endOffset = event.getOffset() + event.getNewLength();
  TextChangeImpl change = new TextChangeImpl(oldText, event.getOffset(), endOffset);
  if (i < 0) {
    myChanges.add(change);
  }
  else {
    myChanges.add(i, change);
  }
}
 
Example 7
Source File: ChangedPsiRangeUtil.java    From consulo with Apache License 2.0 5 votes vote down vote up
@Nullable
static ProperTextRange getChangedPsiRange(@Nonnull PsiFile file, @Nonnull Document document, @Nonnull CharSequence oldDocumentText, @Nonnull CharSequence newDocumentText) {
  int psiLength = oldDocumentText.length();
  if (!file.getViewProvider().supportsIncrementalReparse(file.getLanguage())) {
    return new ProperTextRange(0, psiLength);
  }
  List<DocumentEvent> events = ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(file.getProject())).getEventsSinceCommit(document);
  int prefix = Integer.MAX_VALUE;
  int suffix = Integer.MAX_VALUE;
  int lengthBeforeEvent = psiLength;
  for (DocumentEvent event : events) {
    prefix = Math.min(prefix, event.getOffset());
    suffix = Math.min(suffix, lengthBeforeEvent - event.getOffset() - event.getOldLength());
    lengthBeforeEvent = lengthBeforeEvent - event.getOldLength() + event.getNewLength();
  }
  if ((prefix == psiLength || suffix == psiLength) && newDocumentText.length() == psiLength) {
    return null;
  }
  //Important! delete+insert sequence can give some of same chars back, lets grow affixes to include them.
  int shortestLength = Math.min(psiLength, newDocumentText.length());
  while (prefix < shortestLength && oldDocumentText.charAt(prefix) == newDocumentText.charAt(prefix)) {
    prefix++;
  }
  while (suffix < shortestLength - prefix && oldDocumentText.charAt(psiLength - suffix - 1) == newDocumentText.charAt(newDocumentText.length() - suffix - 1)) {
    suffix++;
  }
  int end = Math.max(prefix, psiLength - suffix);
  if (end == prefix && newDocumentText.length() == oldDocumentText.length()) return null;
  return ProperTextRange.create(prefix, end);
}
 
Example 8
Source File: OffsetTranslator.java    From consulo with Apache License 2.0 5 votes vote down vote up
@Nullable
private static Integer translateOffset(int offset, DocumentEvent event) {
  if (event.getOffset() < offset && offset < event.getOffset() + event.getNewLength()) {
    if (event.getOldLength() == 0) {
      return event.getOffset();
    }

    return null;
  }

  return offset <= event.getOffset() ? offset : offset - event.getNewLength() + event.getOldLength();
}
 
Example 9
Source File: LineOrientedDocumentChangeAdapter.java    From consulo with Apache License 2.0 5 votes vote down vote up
@Override
public void documentChanged(DocumentEvent event) {
  Document document = event.getDocument();
  int startLine = document.getLineNumber(normalize(event.getDocument(), event.getOffset()));
  int endLine = document.getLineNumber(normalize(event.getDocument(), event.getOffset() + event.getNewLength()));
  int symbolsDifference = event.getNewLength() - event.getOldLength();
  afterDocumentChange(startLine, endLine, symbolsDifference);
}
 
Example 10
Source File: EditorSizeManager.java    From consulo with Apache License 2.0 5 votes vote down vote up
@Override
public void beforeDocumentChange(@Nonnull DocumentEvent event) {
  myAfterLineEndInlayUpdated = false;
  myDuringDocumentUpdate = true;
  if (myDocument.isInBulkUpdate()) return;
  myDocumentChangeStartOffset = event.getOffset();
  myDocumentChangeEndOffset = event.getOffset() + event.getNewLength();
}
 
Example 11
Source File: TextInputListener.java    From tmc-intellij with MIT License 5 votes vote down vote up
private boolean isPasteEvent(DocumentEvent documentEvent) {
    if (ClipboardService.getClipBoard() == null) {
        return false;
    }
    return (documentEvent.getNewLength() > 2)
            && ClipboardService.getClipBoard()
                    .trim()
                    .equals(documentEvent.getNewFragment().toString().trim());
}
 
Example 12
Source File: EditorEventManager.java    From lsp4intellij with Apache License 2.0 4 votes vote down vote up
public void documentChanged(DocumentEvent event) {
    if (editor.isDisposed()) {
        return;
    }
    if (event.getDocument() == editor.getDocument()) {
        //Todo - restore when adding hover support
        // long predTime = System.nanoTime(); //So that there are no hover events while typing
        changesParams.getTextDocument().setVersion(version++);

        if (syncKind == TextDocumentSyncKind.Incremental) {
            TextDocumentContentChangeEvent changeEvent = changesParams.getContentChanges().get(0);
            CharSequence newText = event.getNewFragment();
            int offset = event.getOffset();
            int newTextLength = event.getNewLength();
            Position lspPosition = DocumentUtils.offsetToLSPPos(editor, offset);
            int startLine = lspPosition.getLine();
            int startColumn = lspPosition.getCharacter();
            CharSequence oldText = event.getOldFragment();

            //if text was deleted/replaced, calculate the end position of inserted/deleted text
            int endLine, endColumn;
            if (oldText.length() > 0) {
                endLine = startLine + StringUtil.countNewLines(oldText);
                String[] oldLines = oldText.toString().split("\n");
                int oldTextLength = oldLines.length == 0 ? 0 : oldLines[oldLines.length - 1].length();
                endColumn = oldLines.length == 1 ? startColumn + oldTextLength : oldTextLength;
            } else { //if insert or no text change, the end position is the same
                endLine = startLine;
                endColumn = startColumn;
            }
            Range range = new Range(new Position(startLine, startColumn), new Position(endLine, endColumn));
            changeEvent.setRange(range);
            changeEvent.setRangeLength(newTextLength);
            changeEvent.setText(newText.toString());
        } else if (syncKind == TextDocumentSyncKind.Full) {
            changesParams.getContentChanges().get(0).setText(editor.getDocument().getText());
        }
        requestManager.didChange(changesParams);
    } else {
        LOG.error("Wrong document for the EditorEventManager");
    }
}
 
Example 13
Source File: EditorComponentImpl.java    From consulo with Apache License 2.0 4 votes vote down vote up
/** Redispatch an IDE {@link DocumentEvent} to a Swing {@link javax.swing.event.DocumentListener} */
private void fireJTextComponentDocumentChange(final DocumentEvent event) {
  //noinspection deprecation
  List<javax.swing.event.DocumentListener> listeners = ((EditorAccessibilityDocument)getDocument()).getListeners();
  if (listeners == null) {
    return;
  }

  javax.swing.event.DocumentEvent swingEvent = new javax.swing.event.DocumentEvent() {
    @Override
    public int getOffset() {
      return event.getOffset();
    }

    @Override
    public int getLength() {
      return event.getNewLength();
    }

    @Override
    public javax.swing.text.Document getDocument() {
      //noinspection deprecation
      return EditorComponentImpl.this.getDocument();
    }

    @Override
    public EventType getType() {
      return event.getOldLength() == 0 ? EventType.INSERT : event.getNewLength() == 0 ? EventType.REMOVE : EventType.CHANGE;
    }

    @Nullable
    @Override
    public ElementChange getChange(Element element) {
      return null;
    }
  };
  for (javax.swing.event.DocumentListener listener : listeners) {
    javax.swing.event.DocumentEvent.EventType type = swingEvent.getType();
    if (type == javax.swing.event.DocumentEvent.EventType.INSERT) {
      listener.insertUpdate(swingEvent);
    } else if (type == javax.swing.event.DocumentEvent.EventType.REMOVE) {
      listener.removeUpdate(swingEvent);
    } else if (type == javax.swing.event.DocumentEvent.EventType.CHANGE) {
      listener.changedUpdate(swingEvent);
    }
  }
}
 
Example 14
Source File: DesktopCaretImpl.java    From consulo with Apache License 2.0 4 votes vote down vote up
@Override
protected void changedUpdateImpl(@Nonnull DocumentEvent e) {
  int oldOffset = intervalStart();
  super.changedUpdateImpl(e);
  if (isValid()) {
    // Under certain conditions, when text is inserted at caret position, we position caret at the end of inserted text.
    // Ideally, client code should be responsible for positioning caret after document modification, but in case of
    // postponed formatting (after PSI modifications), this is hard to implement, so a heuristic below is used.
    if (e.getOldLength() == 0 &&
        oldOffset == e.getOffset() &&
        !Boolean.TRUE.equals(myEditor.getUserData(DesktopEditorImpl.DISABLE_CARET_SHIFT_ON_WHITESPACE_INSERTION)) &&
        needToShiftWhiteSpaces(e)) {
      int afterInserted = e.getOffset() + e.getNewLength();
      setIntervalStart(afterInserted);
      setIntervalEnd(afterInserted);
    }
    int offset = intervalStart();
    if (DocumentUtil.isInsideSurrogatePair(getDocument(), offset)) {
      setIntervalStart(offset - 1);
      setIntervalEnd(offset - 1);
    }
  }
  else {
    setValid(true);
    int newOffset = Math.min(intervalStart(), e.getOffset() + e.getNewLength());
    if (!e.getDocument().isInBulkUpdate() && e.isWholeTextReplaced()) {
      try {
        final int line = ((DocumentEventImpl)e).translateLineViaDiff(myLogicalCaret.line);
        newOffset = myEditor.logicalPositionToOffset(new LogicalPosition(line, myLogicalCaret.column));
      }
      catch (FilesTooBigForDiffException ex) {
        LOG.info(ex);
      }
    }
    newOffset = DocumentUtil.alignToCodePointBoundary(getDocument(), newOffset);
    setIntervalStart(newOffset);
    setIntervalEnd(newOffset);
  }
  myLogicalColumnAdjustment = 0;
  myVisualColumnAdjustment = 0;
  if (oldOffset >= e.getOffset() && oldOffset <= e.getOffset() + e.getOldLength() && e.getNewLength() == 0 && e.getOldLength() > 0) {
    int inlaysToTheLeft = myEditor.getInlayModel().getInlineElementsInRange(e.getOffset(), e.getOffset()).size();
    boolean hasInlaysToTheRight = myEditor.getInlayModel().hasInlineElementAt(e.getOffset() + e.getOldLength());
    if (inlaysToTheLeft > 0 || hasInlaysToTheRight) {
      myLeansTowardsLargerOffsets = !hasInlaysToTheRight;
      myVisualColumnAdjustment = hasInlaysToTheRight ? inlaysToTheLeft : 0;
    }
    else if (oldOffset == e.getOffset()) {
      myLeansTowardsLargerOffsets = false;
    }
  }
}
 
Example 15
Source File: RangeMarkerImpl.java    From consulo with Apache License 2.0 4 votes vote down vote up
@Nullable
static TextRange applyChange(@Nonnull DocumentEvent e, int intervalStart, int intervalEnd, boolean isGreedyToLeft, boolean isGreedyToRight, boolean isStickingToRight) {
  if (intervalStart == intervalEnd) {
    return processIfOnePoint(e, intervalStart, isGreedyToRight, isStickingToRight);
  }

  final int offset = e.getOffset();
  final int oldLength = e.getOldLength();
  final int newLength = e.getNewLength();

  // changes after the end.
  if (intervalEnd < offset) {
    return new UnfairTextRange(intervalStart, intervalEnd);
  }
  if (!isGreedyToRight && intervalEnd == offset) {
    // handle replaceString that was minimized and resulted in insertString at the range end
    if (e instanceof DocumentEventImpl && oldLength == 0 && ((DocumentEventImpl)e).getInitialStartOffset() < offset) {
      return new UnfairTextRange(intervalStart, intervalEnd + newLength);
    }
    return new UnfairTextRange(intervalStart, intervalEnd);
  }

  // changes before start
  if (intervalStart > offset + oldLength) {
    return new UnfairTextRange(intervalStart + newLength - oldLength, intervalEnd + newLength - oldLength);
  }
  if (!isGreedyToLeft && intervalStart == offset + oldLength) {
    // handle replaceString that was minimized and resulted in insertString at the range start
    if (e instanceof DocumentEventImpl && oldLength == 0 && ((DocumentEventImpl)e).getInitialStartOffset() + ((DocumentEventImpl)e).getInitialOldLength() > offset) {
      return new UnfairTextRange(intervalStart, intervalEnd + newLength);
    }
    return new UnfairTextRange(intervalStart + newLength - oldLength, intervalEnd + newLength - oldLength);
  }

  // Changes inside marker's area. Expand/collapse.
  if (intervalStart <= offset && intervalEnd >= offset + oldLength) {
    return new ProperTextRange(intervalStart, intervalEnd + newLength - oldLength);
  }

  // At this point we either have (myStart xor myEnd inside changed area) or whole area changed.

  // Replacing prefix or suffix...
  if (intervalStart >= offset && intervalStart <= offset + oldLength && intervalEnd > offset + oldLength) {
    return new ProperTextRange(offset + newLength, intervalEnd + newLength - oldLength);
  }

  if (intervalEnd >= offset && intervalEnd <= offset + oldLength && intervalStart < offset) {
    return new UnfairTextRange(intervalStart, offset);
  }

  return null;
}
 
Example 16
Source File: EmptyEditorHighlighter.java    From consulo with Apache License 2.0 4 votes vote down vote up
@Override
public void documentChanged(DocumentEvent e) {
  myTextLength += e.getNewLength() - e.getOldLength();
}
 
Example 17
Source File: TextInputListener.java    From tmc-intellij with MIT License 4 votes vote down vote up
private boolean isRemoveEvent(DocumentEvent documentEvent) {
    return (documentEvent.getOldLength() > 0 && documentEvent.getNewLength() == 0);
}
 
Example 18
Source File: IncrementalCacheUpdateEvent.java    From consulo with Apache License 2.0 2 votes vote down vote up
/**
 * Creates new {@code IncrementalCacheUpdateEvent} object on the basis on the given event object that describes
 * document change that caused cache update.
 * <p/>
 * This constructor is assumed to be used <b>before</b> the document change.
 *
 * @param event object that describes document change that caused cache update
 */
IncrementalCacheUpdateEvent(@Nonnull DocumentEvent event, @Nonnull DesktopEditorImpl editor) {
  this(event.getOffset(), event.getOffset() + event.getOldLength(), event.getOffset() + event.getNewLength(), editor);
}