PY-10182 Initial implementation of pycodestyle's option "--hang-closing" in Python formatter

This commit is contained in:
Mikhail Golubev
2017-01-13 11:58:33 +03:00
parent 759f2fc825
commit 4e3322a0eb
13 changed files with 86 additions and 12 deletions
@@ -1035,6 +1035,7 @@ formatter.align.when.multiline=Align when multiline
formatter.collections.and.comprehensions=Collections and Comprehensions
formatter.import.statements=Import Statements
formatter.dictionary.literals=Dictionary literals
formatter.hang.closing.brackets=Hang closing brackets
smartKeys.insert.backslash.in.statement.on.enter=Insert backslash when pressing Enter inside a statement
smartKeys.insert.self.in.method=Insert 'self' when defining a method
@@ -250,7 +250,7 @@ public class PyBlock implements ASTBlock {
final PyCodeStyleSettings settings = CodeStyleSettingsManager.getSettings(child.getPsi().getProject()).getCustomSettings(PyCodeStyleSettings.class);
if (parentType == PyElementTypes.LIST_LITERAL_EXPRESSION || parentType == PyElementTypes.LIST_COMP_EXPRESSION) {
if (childType == PyTokenTypes.RBRACKET || childType == PyTokenTypes.LBRACKET) {
if ((childType == PyTokenTypes.RBRACKET && !settings.HANG_CLOSING_BRACKETS) || childType == PyTokenTypes.LBRACKET) {
childIndent = Indent.getNoneIndent();
}
else {
@@ -259,7 +259,7 @@ public class PyBlock implements ASTBlock {
}
else if (parentType == PyElementTypes.DICT_LITERAL_EXPRESSION || parentType == PyElementTypes.SET_LITERAL_EXPRESSION ||
parentType == PyElementTypes.SET_COMP_EXPRESSION || parentType == PyElementTypes.DICT_COMP_EXPRESSION) {
if (childType == PyTokenTypes.RBRACE || !hasLineBreaksBeforeInSameParent(child, 1)) {
if ((childType == PyTokenTypes.RBRACE && !settings.HANG_CLOSING_BRACKETS) || !hasLineBreaksBeforeInSameParent(child, 1)) {
childIndent = Indent.getNoneIndent();
}
else {
@@ -283,7 +283,7 @@ public class PyBlock implements ASTBlock {
}
if (childType == PyTokenTypes.RPAR) {
childIndent = Indent.getNoneIndent();
if (!hasHangingIndent(myNode.getPsi())) {
if (!hasHangingIndent(myNode.getPsi()) || settings.HANG_CLOSING_BRACKETS) {
childAlignment = getAlignmentForChildren();
}
}
@@ -320,18 +320,16 @@ public class PyBlock implements ASTBlock {
}
}
else if (parentType == PyElementTypes.ARGUMENT_LIST || parentType == PyElementTypes.PARAMETER_LIST) {
if (childType == PyTokenTypes.RPAR) {
if (childType == PyTokenTypes.RPAR && !settings.HANG_CLOSING_BRACKETS) {
childIndent = Indent.getNoneIndent();
}
else if (parentType == PyElementTypes.PARAMETER_LIST ||
settings.USE_CONTINUATION_INDENT_FOR_ARGUMENTS ||
argumentMayHaveSameIndentAsFollowingStatementList()) {
childIndent = Indent.getContinuationIndent();
}
else {
if (parentType == PyElementTypes.PARAMETER_LIST ||
settings.USE_CONTINUATION_INDENT_FOR_ARGUMENTS ||
argumentMayHaveSameIndentAsFollowingStatementList()) {
childIndent = Indent.getContinuationIndent();
}
else {
childIndent = Indent.getNormalIndent();
}
childIndent = Indent.getNormalIndent();
}
}
else if (parentType == PyElementTypes.SUBSCRIPTION_EXPRESSION) {
@@ -93,6 +93,13 @@ public class PyCodeStyleSettings extends CustomCodeStyleSettings {
public boolean OPTIMIZE_IMPORTS_SORT_BY_TYPE_FIRST = true;
public boolean OPTIMIZE_IMPORTS_JOIN_FROM_IMPORTS_WITH_SAME_SOURCE = false;
/**
* Corresponds to the option of pycodestyle.py "--hang-closing". Basically, it means that the closing brace of a collection literal,
* a comprehension, an argument list, a parameter list or parentheses in "from" import statement should have the same indent as the items
* inside even if there is so called hanging indent (nothing follows the opening bracket on its line).
*/
public boolean HANG_CLOSING_BRACKETS = false;
public PyCodeStyleSettings(CodeStyleSettings container) {
super("Python", container);
}
@@ -129,6 +129,7 @@ public class PyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettin
consumer.showCustomOption(PyCodeStyleSettings.class, "DICT_NEW_LINE_BEFORE_RIGHT_BRACE",
ApplicationBundle.message("wrapping.rbrace.on.new.line"),
PyBundle.message("formatter.dictionary.literals"));
consumer.showCustomOption(PyCodeStyleSettings.class, "HANG_CLOSING_BRACKETS", PyBundle.message("formatter.hang.closing.brackets"), null);
}
}
@@ -0,0 +1,5 @@
from module import (
A,
B,
C,
)
@@ -0,0 +1,5 @@
from module import (
A,
B,
C,
)
@@ -0,0 +1,5 @@
func(
1,
2,
3
)
@@ -0,0 +1,5 @@
func(
1,
2,
3
)
@@ -0,0 +1,6 @@
def func(
x,
y,
z
):
pass
@@ -0,0 +1,6 @@
def func(
x,
y,
z
):
pass
@@ -0,0 +1,5 @@
xs = [
1,
2,
3
]
@@ -0,0 +1,5 @@
xs = [
1,
2,
3
]
@@ -674,6 +674,31 @@ public class PyFormatterTest extends PyTestCase {
doTest();
}
// PY-10182
public void testHangClosingParenthesisInFromImport() {
getPythonCodeStyleSettings().HANG_CLOSING_BRACKETS = true;
doTest();
}
// PY-10182
public void testHangClosingParenthesisInFunctionCall() {
getPythonCodeStyleSettings().HANG_CLOSING_BRACKETS = true;
doTest();
}
// PY-10182
public void testHangClosingParenthesisInFunctionDefinition() {
getPythonCodeStyleSettings().HANG_CLOSING_BRACKETS = true;
doTest();
}
// PY-10182
public void testHangClosingParenthesisInListLiteral() {
getPythonCodeStyleSettings().HANG_CLOSING_BRACKETS = true;
doTest();
}
public void testVariableAnnotations() {
runWithLanguageLevel(LanguageLevel.PYTHON36, this::doTest);
}