From 0f0ee7d7314420c98cd1795241edd2b7eb187a8b Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Wed, 13 Jan 2016 16:14:53 +0300 Subject: [PATCH] PY-13304, PY-17979 Add option that allows to use continuation indent for arguments --- .../com/jetbrains/python/PyBundle.properties | 1 + .../jetbrains/python/formatter/PyBlock.java | 4 ++- .../python/formatter/PyCodeStylePanel.form | 12 +++++++-- .../python/formatter/PyCodeStylePanel.java | 27 ++++++++++++++++--- .../python/formatter/PyCodeStyleSettings.java | 8 ++++++ ...ntinuationIndentBeforeFunctionArguments.py | 10 +++++++ ...tionIndentBeforeFunctionArguments_after.py | 10 +++++++ .../com/jetbrains/python/PyFormatterTest.java | 6 +++++ 8 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 python/testData/formatter/continuationIndentBeforeFunctionArguments.py create mode 100644 python/testData/formatter/continuationIndentBeforeFunctionArguments_after.py diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index c28fa7a526a0..be923916065a 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -965,6 +965,7 @@ formatter.panel.dict.alignment.align.on.colon=Align on colon formatter.panel.dict.alignment.align.on.value=Align on value formatter.panel.dict.alignment.label=Dict alignment: formatter.panel.add.trailing.line.feed=Add line feed at the end of file +formatter.panel.use.continuation.indent.for.arguments=Use continuation indent for arguments formatter.left.bracket = Left bracket formatter.around.eq.in.named.parameter = Around = in named parameter diff --git a/python/src/com/jetbrains/python/formatter/PyBlock.java b/python/src/com/jetbrains/python/formatter/PyBlock.java index 461e0fad9b90..4afd0d362595 100644 --- a/python/src/com/jetbrains/python/formatter/PyBlock.java +++ b/python/src/com/jetbrains/python/formatter/PyBlock.java @@ -324,7 +324,9 @@ public class PyBlock implements ASTBlock { childIndent = Indent.getNoneIndent(); } else { - if (parentType == PyElementTypes.PARAMETER_LIST || argumentMayHaveSameIndentAsFollowingStatementList()) { + if (parentType == PyElementTypes.PARAMETER_LIST || + settings.USE_CONTINUATION_INDENT_FOR_ARGUMENTS || + argumentMayHaveSameIndentAsFollowingStatementList()) { childIndent = Indent.getContinuationIndent(); } else { diff --git a/python/src/com/jetbrains/python/formatter/PyCodeStylePanel.form b/python/src/com/jetbrains/python/formatter/PyCodeStylePanel.form index 392973f56cd5..1bedd0b8863b 100644 --- a/python/src/com/jetbrains/python/formatter/PyCodeStylePanel.form +++ b/python/src/com/jetbrains/python/formatter/PyCodeStylePanel.form @@ -23,7 +23,7 @@ - + @@ -47,12 +47,20 @@ - + + + + + + + + + diff --git a/python/src/com/jetbrains/python/formatter/PyCodeStylePanel.java b/python/src/com/jetbrains/python/formatter/PyCodeStylePanel.java index 00334078dc9b..2d18301ff07b 100644 --- a/python/src/com/jetbrains/python/formatter/PyCodeStylePanel.java +++ b/python/src/com/jetbrains/python/formatter/PyCodeStylePanel.java @@ -43,6 +43,7 @@ public class PyCodeStylePanel extends CodeStyleAbstractPanel { private JPanel myPanel; private JBCheckBox myAddTrailingBlankLineCheckbox; + private JBCheckBox myUseContinuationIndentForArguments; private ComboBox myDictAlignmentCombo; private JPanel myPreviewPanel; @@ -71,6 +72,13 @@ public class PyCodeStylePanel extends CodeStyleAbstractPanel { somethingChanged(); } }); + + myUseContinuationIndentForArguments.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + somethingChanged(); + } + }); } @Override @@ -103,6 +111,7 @@ public class PyCodeStylePanel extends CodeStyleAbstractPanel { } } myAddTrailingBlankLineCheckbox.setSelected(getCustomSettings(settings).BLANK_LINE_AT_FILE_END); + myUseContinuationIndentForArguments.setSelected(getCustomSettings(settings).USE_CONTINUATION_INDENT_FOR_ARGUMENTS); } @Override @@ -110,6 +119,7 @@ public class PyCodeStylePanel extends CodeStyleAbstractPanel { final PyCodeStyleSettings customSettings = getCustomSettings(settings); customSettings.DICT_ALIGNMENT = getDictAlignmentAsInt(); customSettings.BLANK_LINE_AT_FILE_END = ensureTrailingBlankLine(); + customSettings.USE_CONTINUATION_INDENT_FOR_ARGUMENTS = useContinuationIndentForArguments(); } @Override @@ -137,8 +147,17 @@ public class PyCodeStylePanel extends CodeStyleAbstractPanel { return myAddTrailingBlankLineCheckbox.isSelected(); } - public static final String PREVIEW = "{\n" + - " \"green\": 42,\n" + - " \"eggs and ham\": -0.0e0\n" + - "}"; + private boolean useContinuationIndentForArguments() { + return myUseContinuationIndentForArguments.isSelected(); + } + + public static final String PREVIEW = "x = max(\n" + + " 1,\n" + + " 2,\n" + + " 3)\n" + + "\n" + + "{\n" + + " \"green\": 42,\n" + + " \"eggs and ham\": -0.0e0\n" + + "}"; } diff --git a/python/src/com/jetbrains/python/formatter/PyCodeStyleSettings.java b/python/src/com/jetbrains/python/formatter/PyCodeStyleSettings.java index 6b75cd2ef9f6..e87b16768cd5 100644 --- a/python/src/com/jetbrains/python/formatter/PyCodeStyleSettings.java +++ b/python/src/com/jetbrains/python/formatter/PyCodeStyleSettings.java @@ -78,6 +78,14 @@ public class PyCodeStyleSettings extends CustomCodeStyleSettings { public boolean DICT_NEW_LINE_BEFORE_RIGHT_BRACE = false; public int BLANK_LINES_AFTER_LOCAL_IMPORTS = 0; + /** + * Code style for most languages use continuation indent both for parameters in function definition and for arguments in function calls. + * In Python continuation indent (assuming it's 8 spaces) for parameters is required by PEP 8, because otherwise they won't be visually + * distinctive from function body. However for arguments (except several special cases) both normal and continuation indents are acceptable + * (as long as they're multiple of 4), though examples in PEP 8 itself use mostly normal indent. Nontheless some users prefer to have + * the same indetation level for arguments as for parameters. + */ + public boolean USE_CONTINUATION_INDENT_FOR_ARGUMENTS = false; public PyCodeStyleSettings(CodeStyleSettings container) { super("Python", container); diff --git a/python/testData/formatter/continuationIndentBeforeFunctionArguments.py b/python/testData/formatter/continuationIndentBeforeFunctionArguments.py new file mode 100644 index 000000000000..ace58e4ed49a --- /dev/null +++ b/python/testData/formatter/continuationIndentBeforeFunctionArguments.py @@ -0,0 +1,10 @@ +sum( + 1, + 2, 3, +5, +) + +sum( +1, + 2, 3, + 5) diff --git a/python/testData/formatter/continuationIndentBeforeFunctionArguments_after.py b/python/testData/formatter/continuationIndentBeforeFunctionArguments_after.py new file mode 100644 index 000000000000..152610f98170 --- /dev/null +++ b/python/testData/formatter/continuationIndentBeforeFunctionArguments_after.py @@ -0,0 +1,10 @@ +sum( + 1, + 2, 3, + 5, +) + +sum( + 1, + 2, 3, + 5) diff --git a/python/testSrc/com/jetbrains/python/PyFormatterTest.java b/python/testSrc/com/jetbrains/python/PyFormatterTest.java index 575abfd664be..030542de8dca 100644 --- a/python/testSrc/com/jetbrains/python/PyFormatterTest.java +++ b/python/testSrc/com/jetbrains/python/PyFormatterTest.java @@ -659,4 +659,10 @@ public class PyFormatterTest extends PyTestCase { public void testBlanksBetweenImportsPreservedWithoutOptimizeImports() { doTest(); } + + // PY-17979, PY-13304 + public void testContinuationIndentBeforeFunctionArguments() { + getPythonCodeStyleSettings().USE_CONTINUATION_INDENT_FOR_ARGUMENTS = true; + doTest(); + } }