int (@NotNull Editor editor, @NotNull String s, boolean toProcessOverwriteMode, boolean toMoveCaret, int caretShift) { // There is a possible case that particular soft wraps become hard wraps if the caret is located at soft wrap-introduced virtual // space, hence, we need to give editor a chance to react accordingly. editor.getSoftWrapModel().beforeDocumentChangeAtCaret(); int oldOffset = editor.getSelectionModel().getSelectionStart(); String filler = editor.getSelectionModel().hasSelection() ? "" : calcStringToFillVirtualSpace(editor); if (!filler.isEmpty()) { s = filler + s; } Document document = editor.getDocument(); SelectionModel selectionModel = editor.getSelectionModel(); if (editor.isInsertMode() || !toProcessOverwriteMode) { if (selectionModel.hasSelection()) { document.replaceString(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd(), s); } else { document.insertString(oldOffset, s); } } else { deleteSelectedText(editor); if (s.length() == 1 && Character.isLowSurrogate(s.charAt(0)) && oldOffset > 0 && Character.isHighSurrogate(document.getImmutableCharSequence().charAt(oldOffset - 1))) { // Hack to support input of surrogate pairs in editor via InputMethodEvent. // Such input is processed char-by-char using EditorImpl.processKeyTyped. document.insertString(oldOffset, s); } else { int lineNumber = editor.getCaretModel().getLogicalPosition().line; int lineEndOffset = document.getLineEndOffset(lineNumber); int inputCodePointCount = s.codePointCount(0, s.length()); int endOffset; try { endOffset = Math.min(lineEndOffset, Character.offsetByCodePoints(document.getImmutableCharSequence(), oldOffset, inputCodePointCount)); } catch (IndexOutOfBoundsException e) { endOffset = lineEndOffset; } document.replaceString(oldOffset, endOffset, s); } } int offset = oldOffset + filler.length() + caretShift; if (toMoveCaret){ editor.getCaretModel().moveToVisualPosition(editor.offsetToVisualPosition(offset, false, true)); selectionModel.removeSelection(); } else if (editor.getCaretModel().getOffset() != oldOffset) { // handling the case when caret model tracks document changes editor.getCaretModel().moveToOffset(oldOffset); } return offset; }