mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 15:09:39 +07:00
PY-14962 Allow to specify wrapping for key-value pairs of dict literals
This commit is contained in:
@@ -88,6 +88,7 @@ public class PyBlock implements ASTBlock {
|
||||
private List<PyBlock> mySubBlocks = null;
|
||||
private Alignment myChildAlignment;
|
||||
private final Alignment myDictAlignment;
|
||||
private final Wrap myDictWrapping;
|
||||
private final boolean myEmptySequence;
|
||||
|
||||
public PyBlock(final PyBlock parent,
|
||||
@@ -104,7 +105,14 @@ public class PyBlock implements ASTBlock {
|
||||
myContext = context;
|
||||
myEmptySequence = isEmptySequence(node);
|
||||
|
||||
myDictAlignment = node.getElementType() == PyElementTypes.DICT_LITERAL_EXPRESSION ? Alignment.createAlignment(true) : null;
|
||||
if (node.getElementType() == PyElementTypes.DICT_LITERAL_EXPRESSION) {
|
||||
myDictAlignment = Alignment.createAlignment(true);
|
||||
myDictWrapping = Wrap.createWrap(myContext.getPySettings().DICT_WRAPPING, true);
|
||||
}
|
||||
else {
|
||||
myDictAlignment = null;
|
||||
myDictWrapping = null;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -267,11 +275,8 @@ public class PyBlock implements ASTBlock {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parentType == PyElementTypes.KEY_VALUE_EXPRESSION) {
|
||||
final PyKeyValueExpression keyValue = (PyKeyValueExpression)myNode.getPsi();
|
||||
if (keyValue != null && child.getPsi() == keyValue.getValue()) {
|
||||
childIndent = Indent.getNormalIndent();
|
||||
}
|
||||
else if (isValueOfKeyValuePair(child)) {
|
||||
childIndent = Indent.getNormalIndent();
|
||||
}
|
||||
//Align elements vertically if there is an argument in the first line of parenthesized expression
|
||||
else if (!hasHangingIndent(myNode.getPsi()) &&
|
||||
@@ -341,23 +346,28 @@ public class PyBlock implements ASTBlock {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (childType == PyElementTypes.KEY_VALUE_EXPRESSION && isChildOfDictLiteral(child)) {
|
||||
wrap = myDictWrapping;
|
||||
childIndent = Indent.getNormalIndent();
|
||||
}
|
||||
|
||||
if (isAfterStatementList(child) && !hasLineBreaksBefore(child, 2) && child.getElementType() != PyTokenTypes.END_OF_LINE_COMMENT) {
|
||||
// maybe enter was pressed and cut us from a previous (nested) statement list
|
||||
childIndent = Indent.getNormalIndent();
|
||||
}
|
||||
|
||||
if (settings.DICT_ALIGNMENT == DICT_ALIGNMENT_ON_VALUE) {
|
||||
if (isDictLiteralPropertyValue(child) && !ourListElementTypes.contains(childType)) {
|
||||
if (isValueOfKeyValuePairOfDictLiteral(child) && !ourListElementTypes.contains(childType)) {
|
||||
childAlignment = myParent.myDictAlignment;
|
||||
}
|
||||
else if (isDictLiteralPropertyValue(myNode) &&
|
||||
else if (isValueOfKeyValuePairOfDictLiteral(myNode) &&
|
||||
ourListElementTypes.contains(parentType) &&
|
||||
PyTokenTypes.OPEN_BRACES.contains(childType)) {
|
||||
childAlignment = myParent.myParent.myDictAlignment;
|
||||
}
|
||||
}
|
||||
else if (myContext.getPySettings().DICT_ALIGNMENT == DICT_ALIGNMENT_ON_COLON) {
|
||||
if (isInsideDictLiteralKeyValue(child) && childType == PyTokenTypes.COLON) {
|
||||
if (isChildOfKeyValuePairOfDictLiteral(child) && childType == PyTokenTypes.COLON) {
|
||||
childAlignment = myParent.myDictAlignment;
|
||||
}
|
||||
}
|
||||
@@ -376,21 +386,26 @@ public class PyBlock implements ASTBlock {
|
||||
return new PyBlock(this, child, childAlignment, childIndent, wrap, myContext);
|
||||
}
|
||||
|
||||
private static boolean isDictLiteralPropertyValue(@NotNull ASTNode node) {
|
||||
return isInsideDictLiteralKeyValue(node) && node.getTreeParent().getPsi(PyKeyValueExpression.class).getValue() == node.getPsi();
|
||||
private static boolean isValueOfKeyValuePairOfDictLiteral(@NotNull ASTNode node) {
|
||||
return isValueOfKeyValuePair(node) && isChildOfDictLiteral(node.getTreeParent());
|
||||
}
|
||||
|
||||
private static boolean isInsideDictLiteralKeyValue(@NotNull ASTNode node) {
|
||||
private static boolean isChildOfKeyValuePairOfDictLiteral(@NotNull ASTNode node) {
|
||||
return isChildOfKeyValuePair(node) && isChildOfDictLiteral(node.getTreeParent());
|
||||
}
|
||||
|
||||
private static boolean isChildOfDictLiteral(@NotNull ASTNode node) {
|
||||
final ASTNode nodeParent = node.getTreeParent();
|
||||
if (nodeParent == null) {
|
||||
return false;
|
||||
}
|
||||
final ASTNode nodeGrandParent = nodeParent.getTreeParent();
|
||||
if (nodeGrandParent == null) {
|
||||
return false;
|
||||
}
|
||||
return nodeParent.getElementType() == PyElementTypes.KEY_VALUE_EXPRESSION &&
|
||||
nodeGrandParent.getElementType() == PyElementTypes.DICT_LITERAL_EXPRESSION;
|
||||
return nodeParent != null && nodeParent.getElementType() == PyElementTypes.DICT_LITERAL_EXPRESSION;
|
||||
}
|
||||
|
||||
private static boolean isChildOfKeyValuePair(@NotNull ASTNode node) {
|
||||
final ASTNode nodeParent = node.getTreeParent();
|
||||
return nodeParent != null && nodeParent.getElementType() == PyElementTypes.KEY_VALUE_EXPRESSION;
|
||||
}
|
||||
|
||||
private static boolean isValueOfKeyValuePair(@NotNull ASTNode node) {
|
||||
return isChildOfKeyValuePair(node) && node.getTreeParent().getPsi(PyKeyValueExpression.class).getValue() == node.getPsi();
|
||||
}
|
||||
|
||||
private static boolean isEmptySequence(@NotNull ASTNode node) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.jetbrains.python.formatter;
|
||||
|
||||
import com.intellij.formatting.WrapType;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
@@ -72,6 +73,8 @@ public class PyCodeStyleSettings extends CustomCodeStyleSettings {
|
||||
public boolean SPACE_BEFORE_NUMBER_SIGN = true;
|
||||
|
||||
public int DICT_ALIGNMENT = DICT_ALIGNMENT_NONE;
|
||||
public int DICT_WRAPPING = WrapType.NORMAL.getLegacyRepresentation();
|
||||
|
||||
|
||||
public PyCodeStyleSettings(CodeStyleSettings container) {
|
||||
super("Python", container);
|
||||
|
||||
@@ -103,6 +103,7 @@ public class PyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettin
|
||||
"Collections and Comprehensions");
|
||||
consumer.showCustomOption(PyCodeStyleSettings.class, "ALIGN_MULTILINE_IMPORTS", "Align when multiline",
|
||||
"Import Statements");
|
||||
consumer.showCustomOption(PyCodeStyleSettings.class, "DICT_WRAPPING", "Dictionary literals", null, WRAP_OPTIONS, WRAP_VALUES);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
python/testData/formatter/dictWrappingChopDownIfLong.py
Normal file
2
python/testData/formatter/dictWrappingChopDownIfLong.py
Normal file
@@ -0,0 +1,2 @@
|
||||
handlers = {ACTION_1: handle_action_1, ACTION_2: handle_action_2, ACTION_3: handle_action_3, ACTION_4: handle_action_4,
|
||||
ACTION_5: handle_action_5, ACTION_6: handle_action_6, ACTION_7: handle_action_7, ACTION_8: handle_action_8}
|
||||
@@ -0,0 +1,9 @@
|
||||
handlers = {
|
||||
ACTION_1: handle_action_1,
|
||||
ACTION_2: handle_action_2,
|
||||
ACTION_3: handle_action_3,
|
||||
ACTION_4: handle_action_4,
|
||||
ACTION_5: handle_action_5,
|
||||
ACTION_6: handle_action_6,
|
||||
ACTION_7: handle_action_7,
|
||||
ACTION_8: handle_action_8}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.jetbrains.python;
|
||||
|
||||
import com.intellij.formatting.WrapType;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -579,6 +580,13 @@ public class PyFormatterTest extends PyTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-14962
|
||||
public void testDictWrappingChopDownIfLong() {
|
||||
settings().setRightMargin(PythonLanguage.getInstance(), 80);
|
||||
getCustomSettings().DICT_WRAPPING = WrapType.CHOP_DOWN_IF_LONG.getLegacyRepresentation();
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-15530
|
||||
public void testAlignmentInArgumentListWhereFirstArgumentIsEmptyCall() {
|
||||
doTest();
|
||||
|
||||
Reference in New Issue
Block a user