void (@NotNull DocumentEvent e) { int oldOffset = intervalStart(); RangeMarkerTree.RMNode<RangeMarkerEx> node = myNode; long newRange = isValid() && node != null ? applyChange(e, node.toScalarRange(), isGreedyToLeft(), isGreedyToRight(), isStickingToRight()) : -1; if (newRange != -1) { setRange(newRange); // 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(EditorImpl.DISABLE_CARET_SHIFT_ON_WHITESPACE_INSERTION)) && needToShiftWhiteSpaces(e)) { int afterInserted = e.getOffset() + e.getNewLength(); setRange(TextRangeScalarUtil.toScalarRange(afterInserted, afterInserted)); } int offset = intervalStart(); if (DocumentUtil.isInsideSurrogatePair(getDocument(), offset)) { setRange(TextRangeScalarUtil.toScalarRange(offset - 1, offset - 1)); } } else { setValid(true); int newOffset = Math.min(getStartOffset(), e.getOffset() + e.getNewLength()); if (!e.getDocument().isInBulkUpdate() && e.isWholeTextReplaced()) { try { 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); setRange(TextRangeScalarUtil.toScalarRange(newOffset, 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; } } }