void (Editor editor, Caret caret, DataContext dataContext, Project project) { CodeInsightSettings settings = CodeInsightSettings.getInstance(); if (project == null) { myOriginalHandler.execute(editor, caret, dataContext); return; } final Document document = editor.getDocument(); final PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, project); if (file == null) { myOriginalHandler.execute(editor, caret, 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') { boolean fastProcessEnterInsideIndent = true; for(EnterHandlerDelegate delegate: EnterHandlerDelegate.EP_NAME.getExtensionList()) { if (delegate.invokeInsideIndent(offset1, editor, dataContext)) { fastProcessEnterInsideIndent = false; break; } } if (fastProcessEnterInsideIndent) { 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, caret, dataContext); return; } } } } boolean forceIndent = false; boolean forceSkipIndent = false; Ref<Integer> caretOffsetRef = new Ref<>(caretOffset); Ref<Integer> caretAdvanceRef = new Ref<>(0); for(EnterHandlerDelegate delegate: EnterHandlerDelegate.EP_NAME.getExtensionList()) { 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, caret, dataContext); if (!editor.isInsertMode() || forceSkipIndent) { return; } if (settings.SMART_INDENT_ON_ENTER || forceIndent) { caretOffset += 1; caretOffset = CharArrayUtil.shiftForward(editor.getDocument().getCharsSequence(), caretOffset, " \t"); if (DocumentUtil.isAtLineEnd(caretOffset, document)) caretOffset = editor.getCaretModel().getOffset(); } else { caretOffset = editor.getCaretModel().getOffset(); } final DoEnterAction action = new DoEnterAction( file, editor, document, dataContext, caretOffset, !insertSpace, caretAdvanceRef.get(), project ); action.setForceIndent(forceIndent); action.run(); for (EnterHandlerDelegate delegate : EnterHandlerDelegate.EP_NAME.getExtensionList()) { if (delegate.postProcessEnter(file, editor, dataContext) == EnterHandlerDelegate.Result.Stop) { break; } } if (settings.SMART_INDENT_ON_ENTER && action.isIndentAdjustmentNeeded()) { CodeStyleManager.getInstance(project).scheduleIndentAdjustment(document, editor.getCaretModel().getOffset()); } }