Result (@NotNull PsiFile file, @NotNull Editor editor, @NotNull Ref<Integer> caretOffset, @NotNull Ref<Integer> caretAdvance, @NotNull DataContext dataContext, EditorActionHandler originalHandler) { int offset = caretOffset.get(); if (editor instanceof EditorWindow) { file = InjectedLanguageManager.getInstance(file.getProject()).getTopLevelFile(file); editor = InjectedLanguageUtil.getTopLevelEditor(editor); offset = editor.getCaretModel().getOffset(); } if (!(file instanceof PyFile)) { return Result.Continue; } final Boolean isSplitLine = DataManager.getInstance().loadFromDataContext(dataContext, SplitLineAction.SPLIT_LINE_KEY); if (isSplitLine != null) { return Result.Continue; } final Document doc = editor.getDocument(); PsiDocumentManager.getInstance(file.getProject()).commitDocument(doc); final PsiElement element = file.findElementAt(offset); final PsiElement prevElement = offset > 0 ? file.findElementAt(offset - 1) : null; CodeInsightSettings codeInsightSettings = CodeInsightSettings.getInstance(); if (codeInsightSettings.JAVADOC_STUB_ON_ENTER) { PsiElement comment = element; if (comment == null && offset != 0) { comment = prevElement; } int expectedStringStart = editor.getCaretModel().getOffset() - 3; // """ or ''' if (comment != null) { final DocstringState state = canGenerateDocstring(comment, expectedStringStart, doc); if (state != DocstringState.NONE) { insertDocStringStub(editor, comment, state); return Result.Continue; } } } if (element == null) { return Result.Continue; } final ASTNode node = element.getNode(); PsiElement elementParent = element.getParent(); final IElementType nodeType = node.getElementType(); if (nodeType == PyTokenTypes.LPAR) elementParent = elementParent.getParent(); if (elementParent instanceof PyParenthesizedExpression || elementParent instanceof PyGeneratorExpression) return Result.Continue; final PyStringElement stringElement = PsiTreeUtil.getParentOfType(element, PyStringElement.class, false); if (stringElement == null && prevElement == element) { return Result.Continue; } if (stringElement != null && (!stringElement.isFormatted() || nodeType == PyTokenTypes.FSTRING_TEXT || // Caret should be right before the opening brace of an f-string fragment nodeType == PyTokenTypes.FSTRING_FRAGMENT_START || nodeType == PyTokenTypes.FSTRING_END)) { if (stringElement.isTripleQuoted() || nodeType == PyTokenTypes.DOCSTRING) { return Result.Continue; } if (prevElement != null && PsiTreeUtil.isAncestor(stringElement, prevElement, false)) { if (stringElement.getTextOffset() + stringElement.getPrefixLength() >= offset) { return Result.Continue; } final String pref = stringElement.getPrefix(); final String quote = stringElement.getQuote(); // Don't split in the middle of an escape sequence final boolean afterBackslash = "\\".equals(doc.getText(TextRange.from(offset - 1, 1))); final boolean isEscapedQuote = quote.equals(doc.getText(TextRange.from(offset, 1))) && afterBackslash; final boolean isEscapedBackslash = "\\".equals(doc.getText(TextRange.from(offset - 2, 1))) && afterBackslash; if (afterBackslash && !isEscapedQuote && !isEscapedBackslash) return Result.Continue; myPostprocessShift = pref.length() + quote.length(); boolean parenthesiseOnEnter = PyCodeInsightSettings.getInstance().PARENTHESISE_ON_ENTER; final String delimiter = parenthesiseOnEnter ? "" : " \\"; // TODO check for a non-parenthesized sequence pattern here if (PsiTreeUtil.getParentOfType(stringElement, PyEditorHandlerConfig.IMPLICIT_WRAP_CLASSES) != null) { doc.insertString(offset, quote + pref + quote); caretOffset.set(caretOffset.get() + 1); } else { int insertionOffset = offset; if (isEscapedQuote) { // Preserve the escaped quote, split after it caretOffset.set(caretOffset.get() + 1); insertionOffset++; } if (parenthesiseOnEnter) { parenthesise(stringElement, doc); caretOffset.set(caretOffset.get() + 1); insertionOffset++; } doc.insertString(insertionOffset, quote + delimiter + pref + quote); caretOffset.set(caretOffset.get() + delimiter.length() + 1); } return Result.Continue; } } return checkInsertBackslash(file, caretOffset, dataContext, offset, doc); }