Skip to content

Commit

Permalink
Allow to indent and align with tabs instead of spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Vampire committed May 11, 2018
1 parent 12f3222 commit 96776ef
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 29 deletions.
Expand Up @@ -29,7 +29,10 @@
import com.github.javaparser.ast.type.PrimitiveType; import com.github.javaparser.ast.type.PrimitiveType;
import org.junit.Test; import org.junit.Test;


import static com.github.javaparser.JavaParser.*; import static com.github.javaparser.JavaParser.parse;
import static com.github.javaparser.JavaParser.parseBodyDeclaration;
import static com.github.javaparser.printer.PrettyPrinterConfiguration.IndentType.TABS;
import static com.github.javaparser.printer.PrettyPrinterConfiguration.IndentType.TABS_WITH_SPACE_ALIGN;
import static com.github.javaparser.utils.TestUtils.assertEqualsNoEol; import static com.github.javaparser.utils.TestUtils.assertEqualsNoEol;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;


Expand Down Expand Up @@ -222,4 +225,56 @@ public void prettyAlignMethodCallChainsIndentsArgumentsWithBlocksCorrectly() {
" }\n" + " }\n" +
"}\n", printed); "}\n", printed);
} }

@Test
public void indentWithTabsAsFarAsPossible() {

CompilationUnit cu = JavaParser.parse("class Foo { void bar() { foo().bar().baz(() -> { boo().baa().bees(a, b, c); }).bam(); } }");
String printed = new PrettyPrinter(new PrettyPrinterConfiguration()
.setColumnAlignFirstMethodChain(true)
.setColumnAlignParameters(true)
.setIndentType(TABS)
.setIndentSize(1))
.print(cu);

assertEqualsNoEol("class Foo {\n" +
"\n" +
"\tvoid bar() {\n" +
"\t\tfoo().bar()\n" +
"\t\t\t .baz(() -> {\n" +
"\t\t\t\t\t boo().baa()\n" +
"\t\t\t\t\t\t .bees(a,\n" +
"\t\t\t\t\t\t\t\t b,\n" +
"\t\t\t\t\t\t\t\t c);\n" +
"\t\t\t\t })\n" +
"\t\t\t .bam();\n" +
"\t}\n" +
"}\n", printed);
}

@Test
public void indentWithTabsAlignWithSpaces() {

CompilationUnit cu = JavaParser.parse("class Foo { void bar() { foo().bar().baz(() -> { boo().baa().bee(a, b, c); }).bam(); } }");
String printed = new PrettyPrinter(new PrettyPrinterConfiguration()
.setColumnAlignFirstMethodChain(true)
.setColumnAlignParameters(true)
.setIndentType(TABS_WITH_SPACE_ALIGN)
.setIndentSize(1))
.print(cu);

assertEqualsNoEol("class Foo {\n" +
"\n" +
"\tvoid bar() {\n" +
"\t\tfoo().bar()\n" +
"\t\t .baz(() -> {\n" +
"\t\t \tboo().baa()\n" +
"\t\t \t .bee(a,\n" +
"\t\t \t b,\n" +
"\t\t \t c);\n" +
"\t\t })\n" +
"\t\t .bam();\n" +
"\t}\n" +
"}\n", printed);
}
} }
Expand Up @@ -42,7 +42,6 @@
import static com.github.javaparser.ast.observer.ObservableProperty.*; import static com.github.javaparser.ast.observer.ObservableProperty.*;
import static com.github.javaparser.printer.concretesyntaxmodel.CsmConditional.Condition.*; import static com.github.javaparser.printer.concretesyntaxmodel.CsmConditional.Condition.*;
import static com.github.javaparser.printer.concretesyntaxmodel.CsmElement.*; import static com.github.javaparser.printer.concretesyntaxmodel.CsmElement.*;
import static com.github.javaparser.utils.Utils.EOL;


/** /**
* The Concrete Syntax Model for a single node type. It knows the syntax used to represent a certain element in Java * The Concrete Syntax Model for a single node type. It knows the syntax used to represent a certain element in Java
Expand Down Expand Up @@ -934,7 +933,7 @@ public static void genericPrettyPrint(Node node, SourcePrinter printer) {
} }


public static String genericPrettyPrint(Node node) { public static String genericPrettyPrint(Node node) {
SourcePrinter sourcePrinter = new SourcePrinter(" ", EOL); SourcePrinter sourcePrinter = new SourcePrinter();
forClass(node.getClass()).prettyPrint(node, sourcePrinter); forClass(node.getClass()).prettyPrint(node, sourcePrinter);
return sourcePrinter.getSource(); return sourcePrinter.getSource();
} }
Expand Down
Expand Up @@ -56,7 +56,7 @@ public class PrettyPrintVisitor implements VoidVisitor<Void> {


public PrettyPrintVisitor(PrettyPrinterConfiguration prettyPrinterConfiguration) { public PrettyPrintVisitor(PrettyPrinterConfiguration prettyPrinterConfiguration) {
configuration = prettyPrinterConfiguration; configuration = prettyPrinterConfiguration;
printer = new SourcePrinter(configuration.getIndent(), configuration.getEndOfLineCharacter()); printer = new SourcePrinter(configuration);
} }


public String getSource() { public String getSource() {
Expand Down Expand Up @@ -133,7 +133,7 @@ private void printTypeParameters(final NodeList<TypeParameter> args, final Void
private void printArguments(final NodeList<Expression> args, final Void arg) { private void printArguments(final NodeList<Expression> args, final Void arg) {
printer.print("("); printer.print("(");
if (configuration.isColumnAlignParameters()) { if (configuration.isColumnAlignParameters()) {
printer.indentTo(printer.getCursor().column); printer.indentWithAlignTo(printer.getCursor().column);
} }
if (!isNullOrEmpty(args)) { if (!isNullOrEmpty(args)) {
for (final Iterator<Expression> i = args.iterator(); i.hasNext(); ) { for (final Iterator<Expression> i = args.iterator(); i.hasNext(); ) {
Expand Down Expand Up @@ -721,8 +721,7 @@ public void visit(final MethodCallExpr n, final Void arg) {
scope.accept(this, arg); scope.accept(this, arg);
if (configuration.isColumnAlignFirstMethodChain()) { if (configuration.isColumnAlignFirstMethodChain()) {
if (!(scope instanceof MethodCallExpr) || !((MethodCallExpr) scope).getScope().isPresent()) { if (!(scope instanceof MethodCallExpr) || !((MethodCallExpr) scope).getScope().isPresent()) {
printer.unindent(); printer.reindentWithAlignToCursor();
printer.indentToCursor();
} else { } else {
printer.println(); printer.println();
} }
Expand Down
Expand Up @@ -25,20 +25,62 @@


import java.util.function.Function; import java.util.function.Function;


import static com.github.javaparser.printer.PrettyPrinterConfiguration.IndentType.SPACES;
import static com.github.javaparser.printer.PrettyPrinterConfiguration.IndentType.TABS;
import static com.github.javaparser.utils.Utils.EOL; import static com.github.javaparser.utils.Utils.EOL;
import static com.github.javaparser.utils.Utils.assertNonNegative;
import static com.github.javaparser.utils.Utils.assertNotNull; import static com.github.javaparser.utils.Utils.assertNotNull;
import static com.github.javaparser.utils.Utils.assertPositive;


/** /**
* Configuration options for the {@link PrettyPrinter}. * Configuration options for the {@link PrettyPrinter}.
*/ */
public class PrettyPrinterConfiguration { public class PrettyPrinterConfiguration {
public enum IndentType {
/**
* Indent with spaces.
*/
SPACES,

/**
* Indent with tabs as far as possible.
* For proper aligning, the tab width is necessary and by default 4.
*/
TABS,

/**
* Indent with tabs but align with spaces when wrapping and aligning
* method call chains and method call parameters.
*
* <p/><i>Example result:</i>
* <pre>
* class Foo {
*
* \tvoid bar() {
* \t\tfoo().bar()
* \t\t......baz(() -> {
* \t\t..........\tboo().baa()
* \t\t..........\t......bee(a,
* \t\t..........\t..........b,
* \t\t..........\t..........c);
* \t\t..........})
* \t\t......bam();
* \t}
* }
* </pre>
*/
TABS_WITH_SPACE_ALIGN
}

public static final int DEFAULT_MAX_ENUM_CONSTANTS_TO_ALIGN_HORIZONTALLY = 5; public static final int DEFAULT_MAX_ENUM_CONSTANTS_TO_ALIGN_HORIZONTALLY = 5;


private boolean orderImports = false; private boolean orderImports = false;
private boolean printComments = true; private boolean printComments = true;
private boolean printJavadoc = true; private boolean printJavadoc = true;
private boolean columnAlignParameters = false; private boolean columnAlignParameters = false;
private boolean columnAlignFirstMethodChain = false; private boolean columnAlignFirstMethodChain = false;
private IndentType indentType = SPACES;
private int tabWidth = 4;
private int indentSize = 4; private int indentSize = 4;
private String endOfLineCharacter = EOL; private String endOfLineCharacter = EOL;
private Function<PrettyPrinterConfiguration, PrettyPrintVisitor> visitorFactory = PrettyPrintVisitor::new; private Function<PrettyPrinterConfiguration, PrettyPrintVisitor> visitorFactory = PrettyPrintVisitor::new;
Expand All @@ -47,12 +89,20 @@ public class PrettyPrinterConfiguration {
/** /**
* Set the string to use for indenting. For example: "\t", " ", "". * Set the string to use for indenting. For example: "\t", " ", "".
* *
* @deprecated use setIndentSize. Tabs are no longer supported. * @deprecated use {@link #setIndentSize(int)} and {@link #setIndentType(IndentType)}.
*/ */
@Deprecated @Deprecated
public PrettyPrinterConfiguration setIndent(String indent) { public PrettyPrinterConfiguration setIndent(String indent) {
System.err.println("PrettyPrinterConfiguration.setIndent is deprecated, please review the changes."); System.err.println("PrettyPrinterConfiguration.setIndent is deprecated, please review the changes.");
indentSize = indent.length(); if (indent.matches(" *")) {
indentSize = indent.length();
indentType = SPACES;
} else if (indent.matches("\\t+")) {
indentSize = indent.length();
indentType = TABS;
} else {
throw new NotImplementedException();
}
return this; return this;
} }


Expand All @@ -61,8 +111,22 @@ public PrettyPrinterConfiguration setIndent(String indent) {
*/ */
public String getIndent() { public String getIndent() {
StringBuilder indentString = new StringBuilder(); StringBuilder indentString = new StringBuilder();
char indentChar;
switch (indentType) {
case SPACES:
indentChar = ' ';
break;

case TABS:
case TABS_WITH_SPACE_ALIGN:
indentChar = '\t';
break;

default:
throw new AssertionError("Unhandled indent type");
}
for (int i = 0; i < indentSize; i++) { for (int i = 0; i < indentSize; i++) {
indentString.append(' '); indentString.append(indentChar);
} }
return indentString.toString(); return indentString.toString();
} }
Expand All @@ -72,13 +136,40 @@ public int getIndentSize() {
} }


/** /**
* Set the size of the indent in spaces. * Set the size of the indent in characters.
*/ */
public PrettyPrinterConfiguration setIndentSize(int size) { public PrettyPrinterConfiguration setIndentSize(int indentSize) {
if (size < 0) { this.indentSize = assertNonNegative(indentSize);
throw new IllegalArgumentException("Indent must be >= 0"); return this;
} }
this.indentSize = size;
/**
* Get the type of indent to produce.
*/
public IndentType getIndentType() {
return indentType;
}

/**
* Set the type of indent to produce.
*/
public PrettyPrinterConfiguration setIndentType(IndentType indentType) {
this.indentType = assertNotNull(indentType);
return this;
}

/**
* Get the tab width for pretty aligning.
*/
public int getTabWidth() {
return tabWidth;
}

/**
* Set the tab width for pretty aligning.
*/
public PrettyPrinterConfiguration setTabWidth(int tabWidth) {
this.tabWidth = assertPositive(tabWidth);
return this; return this;
} }


Expand Down

0 comments on commit 96776ef

Please sign in to comment.