record ( @NotNull Caret caret, @NotNull VisualPosition position, int lineStartOffset, @NotNull VisualPosition lineStartPosition ) { static @NotNull CaretLineState create(@NotNull Caret caret) { Editor editor = caret.getEditor(); int lineStartOffset = EditorUtil.getNotFoldedLineStartOffset(editor, caret.getOffset()); VisualPosition lineStartPosition = editor.offsetToVisualPosition(lineStartOffset); return new CaretLineState(caret, caret.getVisualPosition(), lineStartOffset, lineStartPosition); } void moveCaretAfterInsertionIfNeeded(int insertionLineStartOffset, int insertionLength) { if (caret.getOffset() != insertionLineStartOffset) { return; } int newLineStartOffset = insertionLineStartOffset + insertionLength; VisualPosition newLineStartPosition = caret.getEditor().offsetToVisualPosition(newLineStartOffset); int lineShift = newLineStartPosition.line - lineStartPosition.line; VisualPosition newPosition = new VisualPosition(position.line + lineShift, position.column, position.leansRight); caret.moveToVisualPosition(newPosition); // the following shouldn't happen, but just to be sure if (caret.getOffset() != newLineStartOffset) { caret.moveToOffset(newLineStartOffset); } } boolean isOnSameLine(@NotNull CaretLineState other) { return lineStartOffset == other.lineStartOffset; } }