diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index dd00b4ba8f7c..fc4fa9966eeb 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -34,6 +34,7 @@ + diff --git a/python/src/com/jetbrains/python/editor/PyEnterAtIndentHandler.java b/python/src/com/jetbrains/python/editor/PyEnterAtIndentHandler.java new file mode 100644 index 000000000000..22df807b1bfa --- /dev/null +++ b/python/src/com/jetbrains/python/editor/PyEnterAtIndentHandler.java @@ -0,0 +1,42 @@ +package com.jetbrains.python.editor; + +import com.intellij.codeInsight.editorActions.BackspaceHandler; +import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegateAdapter; +import com.intellij.injected.editor.EditorWindow; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; +import com.jetbrains.python.psi.PyFile; +import org.jetbrains.annotations.NotNull; + +/** + * @author yole + */ +public class PyEnterAtIndentHandler extends EnterHandlerDelegateAdapter { + @Override + public Result preprocessEnter(@NotNull PsiFile file, + @NotNull Editor editor, + @NotNull Ref caretOffset, + @NotNull Ref caretAdvance, + @NotNull DataContext dataContext, + EditorActionHandler originalHandler) { + int offset = caretOffset.get(); + if (editor instanceof EditorWindow) { + file = InjectedLanguageUtil.getTopLevelFile(file); + editor = InjectedLanguageUtil.getTopLevelEditor(editor); + offset = editor.getCaretModel().getOffset(); + } + if (!(file instanceof PyFile)) { + return Result.Continue; + } + + // honor dedent (PY-3009) + if (BackspaceHandler.isWhitespaceBeforeCaret(editor)) { + return Result.DefaultSkipIndent; + } + return Result.Continue; + } +} diff --git a/python/src/com/jetbrains/python/editor/PythonEnterHandler.java b/python/src/com/jetbrains/python/editor/PythonEnterHandler.java index 6f3a856a881a..424218071db3 100644 --- a/python/src/com/jetbrains/python/editor/PythonEnterHandler.java +++ b/python/src/com/jetbrains/python/editor/PythonEnterHandler.java @@ -65,7 +65,7 @@ public class PythonEnterHandler extends EnterHandlerDelegateAdapter { if (isSplitLine != null) { return Result.Continue; } - Document doc = editor.getDocument(); + final Document doc = editor.getDocument(); PsiDocumentManager.getInstance(file.getProject()).commitDocument(doc); final PsiElement element = file.findElementAt(offset); CodeInsightSettings codeInsightSettings = CodeInsightSettings.getInstance(); @@ -145,6 +145,14 @@ public class PythonEnterHandler extends EnterHandlerDelegateAdapter { if (!PyCodeInsightSettings.getInstance().INSERT_BACKSLASH_ON_WRAP) { return Result.Continue; } + return checkInsertBackslash(file, caretOffset, dataContext, offset, doc); + } + + private static Result checkInsertBackslash(PsiFile file, + Ref caretOffset, + DataContext dataContext, + int offset, + Document doc) { if (offset > 0) { final PsiElement beforeCaret = file.findElementAt(offset - 1); if (beforeCaret instanceof PsiWhiteSpace && beforeCaret.getText().indexOf('\\') >= 0) { diff --git a/python/testSrc/com/jetbrains/python/PyIndentTest.java b/python/testSrc/com/jetbrains/python/PyIndentTest.java index c4149825d674..25d343bc5b8d 100644 --- a/python/testSrc/com/jetbrains/python/PyIndentTest.java +++ b/python/testSrc/com/jetbrains/python/PyIndentTest.java @@ -303,6 +303,16 @@ public class PyIndentTest extends PyTestCase { " )"); } + public void testRespectDedent() { // PY-3009 + doTest("if True:\n" + + " bar\n" + + "", + "if True:\n" + + " bar\n" + + "\n" + + ""); + } + /* TODO: formatter core problem? public void testAlignListBeforeEquals() throws Exception {