Skip to content

Commit 2b26dc4

Browse files
Apply suggestions provided by Federico, add an instance method for alignment and add tests that exercise the interaction between indentation, grouping and alignment
1 parent 006e6d4 commit 2b26dc4

File tree

2 files changed

+73
-4
lines changed
  • src
    • main/java/com/opencastsoftware/prettier4j
    • test/java/com/opencastsoftware/prettier4j

2 files changed

+73
-4
lines changed

src/main/java/com/opencastsoftware/prettier4j/Doc.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,15 @@ public Doc indent(int indent) {
236236
return indent(indent, this);
237237
}
238238

239+
/**
240+
* Align any line breaks within this {@link Doc} to the line position at the start of the {@link Doc}.
241+
*
242+
* @return the aligned document.
243+
*/
244+
public Doc align() {
245+
return align(this);
246+
}
247+
239248
/**
240249
* Bracket the current document by the {@code left} and {@code right} Strings,
241250
* indented by {@code indent} spaces.
@@ -1677,7 +1686,7 @@ public static Doc indent(int indent, Doc doc) {
16771686
}
16781687

16791688
/**
1680-
* Align subsequent lines of the current {@link Doc} to the current position in the line.
1689+
* Align any line breaks within this {@link Doc} to the line position at the start of the {@link Doc}.
16811690
*
16821691
* @param doc the input document
16831692
* @return the aligned document.
@@ -2147,8 +2156,7 @@ private static int layoutEntry(RenderOptions options, Deque<Entry> inQueue, Queu
21472156
} else if (entryDoc instanceof Align) {
21482157
// Eliminate Align
21492158
Align alignDoc = (Align) entryDoc;
2150-
int newIndent = Math.max(0, position - entryIndent);
2151-
inQueue.addFirst(entry(newIndent, entryMargin, alignDoc.doc()));
2159+
inQueue.addFirst(entry(position, entryMargin, alignDoc.doc()));
21522160
} else if (entryDoc instanceof Margin) {
21532161
// Eliminate Margin
21542162
Margin marginDoc = (Margin) entryDoc;
@@ -2173,7 +2181,7 @@ private static int layoutEntry(RenderOptions options, Deque<Entry> inQueue, Queu
21732181
outQueue.add(topEntry);
21742182
} else if (entryDoc instanceof LineOr) {
21752183
// Reset line length
2176-
position = entryIndent;
2184+
position = 0;
21772185
// Note reverse order
21782186
if (entryIndent > 0) {
21792187
// Send out the indent spaces

src/test/java/com/opencastsoftware/prettier4j/DocTest.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,28 @@ void testBracketFlattening() {
244244
assertThat(actual, is(equalTo(expected)));
245245
}
246246

247+
@Test
248+
void testBracketFlatteningWithAlign() {
249+
// Note: the arguments are aligned with the "functionCall" element because bracket doesn't support alignment.
250+
// TODO: Consider adding a `hangingBracket` combinator that aligns the bracket docs with the starting line position
251+
// and the arguments with the opening bracket doc.
252+
String expected = "functionCall(\n"+
253+
Indents.get(12)+"a,\n"+
254+
Indents.get(12)+"b,\n"+
255+
Indents.get(12)+"c\n"+
256+
Indents.get(12)+")";
257+
String actual = text("functionCall")
258+
.append(
259+
Doc.intersperse(
260+
Doc.text(",").append(Doc.lineOrSpace()),
261+
Stream.of("a", "b", "c").map(Doc::text))
262+
.bracket(0, Doc.lineOrEmpty(), Doc.text("("), Doc.text(")"))
263+
.align())
264+
.render(10);
265+
266+
assertThat(actual, is(equalTo(expected)));
267+
}
268+
247269
@Test
248270
void testNestedBracketFlattening() {
249271
String expectedWidth80 = "let x = functionCall(with, args, nestedFunctionCall(with, more, args))";
@@ -276,6 +298,45 @@ void testNestedBracketFlattening() {
276298
assertThat(inputDoc.render(20), is(equalTo(expectedWidth20)));
277299
}
278300

301+
@Test
302+
void testNestedBracketFlatteningWithAlign() {
303+
String expectedWidth80 = "let x = functionCall(with, args, nestedFunctionCall(with, more, args))";
304+
String expectedWidth40 =
305+
"let x = functionCall(\n"+
306+
Indents.get(20)+"with,\n"+
307+
Indents.get(20)+"args,\n"+
308+
Indents.get(20)+"nestedFunctionCall(\n"+
309+
Indents.get(38)+"with,\n"+
310+
Indents.get(38)+"more,\n"+
311+
Indents.get(38)+ "args\n"+
312+
Indents.get(38)+")\n"+
313+
Indents.get(20)+")";
314+
315+
Doc inputDoc = text("let")
316+
.appendSpace(text("x"))
317+
.appendSpace(text("="))
318+
.appendSpace(text("functionCall")
319+
.append(align(
320+
intersperse(
321+
text(",").append(lineOrSpace()),
322+
Stream.concat(
323+
Stream.of("with", "args").map(Doc::text),
324+
Stream.of(text("nestedFunctionCall")
325+
.append(align(
326+
intersperse(
327+
text(",").append(lineOrSpace()),
328+
Stream.of("with", "more", "args").map(Doc::text)
329+
).bracket(0, lineOrEmpty(), text("("), text(")"))
330+
)))
331+
)
332+
).bracket(0, lineOrEmpty(), text("("), text(")"))
333+
))
334+
);
335+
336+
assertThat(inputDoc.render(80), is(equalTo(expectedWidth80)));
337+
assertThat(inputDoc.render(40), is(equalTo(expectedWidth40)));
338+
}
339+
279340
@Test
280341
void testAlignWithMultipleLines() {
281342
String expected =

0 commit comments

Comments
 (0)