public static int insertStringAtCaret( Editor editor, @NotNull String s, boolean toProcessOverwriteMode, boolean toMoveCaret, int caretShift) { final SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.hasSelection()) { editor.getCaretModel().moveToOffset(selectionModel.getSelectionStart(), true); } // 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.getCaretModel().getOffset(); String filler = calcStringToFillVirtualSpace(editor); if (filler.length() > 0) { s = filler + s; } Document document = editor.getDocument(); if (editor.isInsertMode() || !toProcessOverwriteMode) { if (selectionModel.hasSelection()) { oldOffset = selectionModel.getSelectionStart(); document.replaceString( selectionModel.getSelectionStart(), selectionModel.getSelectionEnd(), s); } else { document.insertString(oldOffset, s); } } else { deleteSelectedText(editor); int lineNumber = editor.getCaretModel().getLogicalPosition().line; if (lineNumber >= document.getLineCount()) { return insertStringAtCaret(editor, s, false, toMoveCaret); } int endOffset = document.getLineEndOffset(lineNumber); document.replaceString(oldOffset, Math.min(endOffset, oldOffset + s.length()), s); } int offset = oldOffset + filler.length() + caretShift; if (toMoveCaret) { editor.getCaretModel().moveToOffset(offset, true); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); selectionModel.removeSelection(); } else if (editor.getCaretModel().getOffset() != oldOffset) { // handling the case when caret model tracks document changes editor.getCaretModel().moveToOffset(oldOffset); } return offset; }
public static void pasteTransferableAsBlock( Editor editor, @Nullable Producer<Transferable> producer) { String text = getStringContent(producer); if (text == null) return; int caretLine = editor.getCaretModel().getLogicalPosition().line; int originalCaretLine = caretLine; int selectedLinesCount = 0; final SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.hasBlockSelection()) { final LogicalPosition start = selectionModel.getBlockStart(); final LogicalPosition end = selectionModel.getBlockEnd(); assert start != null; assert end != null; LogicalPosition caret = new LogicalPosition(Math.min(start.line, end.line), Math.min(start.column, end.column)); selectedLinesCount = Math.abs(end.line - start.line); caretLine = caret.line; deleteSelectedText(editor); editor.getCaretModel().moveToLogicalPosition(caret); } LogicalPosition caretToRestore = editor.getCaretModel().getLogicalPosition(); String[] lines = LineTokenizer.tokenize(text.toCharArray(), false); if (lines.length > 1 || selectedLinesCount == 0) { int longestLineLength = 0; for (int i = 0; i < lines.length; i++) { String line = lines[i]; longestLineLength = Math.max(longestLineLength, line.length()); editor .getCaretModel() .moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column)); insertStringAtCaret(editor, line, false, true); } caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + longestLineLength); } else { for (int i = 0; i <= selectedLinesCount; i++) { editor .getCaretModel() .moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column)); insertStringAtCaret(editor, text, false, true); } caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + text.length()); } editor.getCaretModel().moveToLogicalPosition(caretToRestore); zeroWidthBlockSelectionAtCaretColumn(editor, caretLine, caretLine + selectedLinesCount); }
public static void deleteToTargetPosition(@NotNull Editor editor, @NotNull LogicalPosition pos) { LogicalPosition logicalPosition = editor.getCaretModel().getLogicalPosition(); if (logicalPosition.line != pos.line) { LOGGER.error( "Unexpected caret position: " + logicalPosition + ", target indent position: " + pos); return; } if (pos.column < logicalPosition.column) { int targetOffset = editor.logicalPositionToOffset(pos); int offset = editor.getCaretModel().getOffset(); editor.getSelectionModel().setSelection(targetOffset, offset); EditorModificationUtil.deleteSelectedText(editor); } else if (pos.column > logicalPosition.column) { EditorModificationUtil.insertStringAtCaret( editor, StringUtil.repeatSymbol(' ', pos.column - logicalPosition.column)); } }
private void startTemplate( final Editor editor, final String selectionString, final Template template, boolean inSeparateCommand, TemplateEditingListener listener, final PairProcessor<String, String> processor, final Map<String, String> predefinedVarValues) { final TemplateState templateState = initTemplateState(editor); //noinspection unchecked templateState.getProperties().put(ExpressionContext.SELECTION, selectionString); if (listener != null) { templateState.addTemplateStateListener(listener); } Runnable r = () -> { if (selectionString != null) { ApplicationManager.getApplication() .runWriteAction(() -> EditorModificationUtil.deleteSelectedText(editor)); } else { editor.getSelectionModel().removeSelection(); } templateState.start((TemplateImpl) template, processor, predefinedVarValues); }; if (inSeparateCommand) { CommandProcessor.getInstance() .executeCommand( myProject, r, CodeInsightBundle.message("insert.code.template.command"), null); } else { r.run(); } if (shouldSkipInTests()) { if (!templateState.isFinished()) templateState.gotoEnd(false); } }
private void executeWriteActionInner(Editor editor, DataContext dataContext, Project project) { CodeInsightSettings settings = CodeInsightSettings.getInstance(); if (project == null) { myOriginalHandler.execute(editor, dataContext); return; } final Document document = editor.getDocument(); final PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, project); if (file == null) { myOriginalHandler.execute(editor, dataContext); return; } CommandProcessor.getInstance() .setCurrentCommandName(CodeInsightBundle.message("command.name.typing")); EditorModificationUtil.deleteSelectedText(editor); int caretOffset = editor.getCaretModel().getOffset(); CharSequence text = document.getCharsSequence(); int length = document.getTextLength(); if (caretOffset < length && text.charAt(caretOffset) != '\n') { int offset1 = CharArrayUtil.shiftBackward(text, caretOffset, " \t"); if (offset1 < 0 || text.charAt(offset1) == '\n') { int offset2 = CharArrayUtil.shiftForward(text, offset1 + 1, " \t"); boolean isEmptyLine = offset2 >= length || text.charAt(offset2) == '\n'; if (!isEmptyLine) { // we are in leading spaces of a non-empty line myOriginalHandler.execute(editor, dataContext); return; } } } final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); documentManager.commitDocument(document); boolean forceIndent = false; boolean forceSkipIndent = false; Ref<Integer> caretOffsetRef = new Ref<Integer>(caretOffset); Ref<Integer> caretAdvanceRef = new Ref<Integer>(0); final EnterHandlerDelegate[] delegates = Extensions.getExtensions(EnterHandlerDelegate.EP_NAME); for (EnterHandlerDelegate delegate : delegates) { EnterHandlerDelegate.Result result = delegate.preprocessEnter( file, editor, caretOffsetRef, caretAdvanceRef, dataContext, myOriginalHandler); if (caretOffsetRef.get() > document.getTextLength()) { throw new AssertionError("Wrong caret offset change by " + delegate); } if (result == EnterHandlerDelegate.Result.Stop) { return; } if (result != EnterHandlerDelegate.Result.Continue) { if (result == EnterHandlerDelegate.Result.DefaultForceIndent) { forceIndent = true; } else if (result == EnterHandlerDelegate.Result.DefaultSkipIndent) { forceSkipIndent = true; } break; } } text = document.getCharsSequence(); // update after changes done in preprocessEnter() caretOffset = caretOffsetRef.get().intValue(); boolean isFirstColumn = caretOffset == 0 || text.charAt(caretOffset - 1) == '\n'; final boolean insertSpace = !isFirstColumn && !(caretOffset >= text.length() || text.charAt(caretOffset) == ' ' || text.charAt(caretOffset) == '\t'); editor.getCaretModel().moveToOffset(caretOffset); myOriginalHandler.execute(editor, dataContext); if (!editor.isInsertMode() || forceSkipIndent) { return; } if (settings.SMART_INDENT_ON_ENTER || forceIndent) { caretOffset += 1; caretOffset = CharArrayUtil.shiftForward(editor.getDocument().getCharsSequence(), caretOffset, " \t"); } else { caretOffset = editor.getCaretModel().getOffset(); } documentManager.commitAllDocuments(); final DoEnterAction action = new DoEnterAction( file, editor, document, dataContext, caretOffset, !insertSpace, caretAdvanceRef.get(), project); action.setForceIndent(forceIndent); action.run(); documentManager.commitDocument(document); for (EnterHandlerDelegate delegate : delegates) { if (delegate.postProcessEnter(file, editor, dataContext) == EnterHandlerDelegate.Result.Stop) { break; } } documentManager.commitDocument(document); }