List<CaretState> (@NotNull Editor editor, @NotNull LogicalPosition blockStart, @NotNull LogicalPosition blockEnd) { int startLine = Math.max(Math.min(blockStart.line, editor.getDocument().getLineCount() - 1), 0); int endLine = Math.max(Math.min(blockEnd.line, editor.getDocument().getLineCount() - 1), 0); int step = endLine < startLine ? -1 : 1; int count = 1 + Math.abs(endLine - startLine); List<CaretState> caretStates = new LinkedList<>(); boolean hasSelection = false; for (int line = startLine, i = 0; i < count; i++, line += step) { int startColumn = blockStart.column; int endColumn = blockEnd.column; int lineEndOffset = editor.getDocument().getLineEndOffset(line); LogicalPosition lineEndPosition = editor.offsetToLogicalPosition(lineEndOffset); int lineWidth = lineEndPosition.column; if (startColumn > lineWidth && endColumn > lineWidth && !editor.isColumnMode()) { LogicalPosition caretPos = new LogicalPosition(line, Math.min(startColumn, endColumn)); caretStates.add(new CaretState(caretPos, lineEndPosition, lineEndPosition)); } else { LogicalPosition startPos = new LogicalPosition(line, editor.isColumnMode() ? startColumn : Math.min(startColumn, lineWidth)); LogicalPosition endPos = new LogicalPosition(line, editor.isColumnMode() ? endColumn : Math.min(endColumn, lineWidth)); int startOffset = editor.logicalPositionToOffset(startPos); int endOffset = editor.logicalPositionToOffset(endPos); caretStates.add(new CaretState(endPos, startPos, endPos)); hasSelection |= startOffset != endOffset; } } if (hasSelection && !editor.isColumnMode()) { // filtering out lines without selection caretStates.removeIf(state -> Objects.equals(state.getSelectionStart(), state.getSelectionEnd())); } return caretStates; }