Skip to content

Commit

Permalink
Fix indentation for newline preceded by comma
Browse files Browse the repository at this point in the history
Signed-off-by: Hope Hadfield <hhadfiel@redhat.com>
  • Loading branch information
hopehadfield authored and rgrunber committed May 8, 2024
1 parent bd80646 commit 7160575
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.jsonrpc.messages.Either3;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
Expand All @@ -63,6 +64,9 @@ public class FormatterHandler {

private static final char CLOSING_BRACE = '}';
private static final char NEW_LINE = '\n';
private static final char COMMA = ',';
private static final String SPACE = " ";
private static final String TAB = "\t";

private PreferenceManager preferenceManager;

Expand Down Expand Up @@ -114,6 +118,10 @@ private List<org.eclipse.lsp4j.TextEdit> format(ICompilationUnit cu, IDocument d
String sourceToFormat = document.get();
int kind = getFormattingKind(cu, includeComments);
TextEdit format = formatter.format(kind, sourceToFormat, region.getOffset(), region.getLength(), 0, lineDelimiter);
InsertEdit commaIndentationEdit = computeIndentationIfCommaPresent(cu, document, region, options);
if (commaIndentationEdit != null) {
format.addChild(commaIndentationEdit);
}
if (format == null || format.getChildren().length == 0 || monitor.isCanceled()) {
// nothing to return
return Collections.<org.eclipse.lsp4j.TextEdit>emptyList();
Expand All @@ -122,6 +130,34 @@ private List<org.eclipse.lsp4j.TextEdit> format(ICompilationUnit cu, IDocument d
return convertEdits(flatEdit.getChildren(), document);
}

private InsertEdit computeIndentationIfCommaPresent(ICompilationUnit cu, IDocument document, IRegion region, FormattingOptions options) {
int length = region.getLength();
try {
if (document.getChar(region.getOffset() + length) == NEW_LINE) {
for (int i = region.getOffset() + length - 1; i >= region.getOffset(); i--) {
char lastCharacter = document.getChar(i);
if (Character.isWhitespace(lastCharacter)) {
continue;
} else if (lastCharacter == COMMA) {
String newText = "";
int numTabs = Integer.valueOf(getOptions(options, cu).get(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION));
if (options.isInsertSpaces()) {
newText = SPACE.repeat(options.getTabSize() * numTabs);
} else {
newText = TAB.repeat(numTabs);
}
return new InsertEdit(document.getLineOffset(document.getLineOfOffset(region.getOffset()) + 1), newText);
} else {
return null;
}
}
}
return null;
} catch (BadLocationException e) {
return null;
}
}

private int getFormattingKind(ICompilationUnit cu, boolean includeComments) {
int kind = includeComments ? CodeFormatter.F_INCLUDE_COMMENTS : 0;
if (cu.getResource() != null && cu.getResource().getName().equals(IModule.MODULE_INFO_JAVA)) {
Expand Down Expand Up @@ -188,6 +224,11 @@ private static org.eclipse.lsp4j.TextEdit convertEdit(TextEdit edit, IDocument d
int offset = edit.getOffset();
textEdit.setRange(new Range(createPosition(document, offset), createPosition(document, offset + edit.getLength())));
}
if (edit instanceof InsertEdit insertEdit) {
textEdit.setNewText(insertEdit.getText());
int offset = edit.getOffset();
textEdit.setRange(new Range(createPosition(document, offset), createPosition(document, offset)));
}
return textEdit;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,49 @@ public void testFormattingOnTypeReturnAfterEmptyBlock() throws Exception {
assertEquals(expectedText, newText);
}

@Test // https://github.com/redhat-developer/vscode-java/issues/3396
public void testFormattingOnTypeReturnMidline() throws Exception {
ICompilationUnit unit = getWorkingCopy("src/org/sample/Baz.java",
//@formatter:off
"package org.sample;\n"
+ "\n"
+ "public class Baz {\n"
+ " public String print() {\n"
+ " int a = 1;\n"
+ " return String.format(\"Value: {}\",\n"
+ " a);\n"
+ " }\n"
+ "}"
//@formatter:on
);

String uri = JDTUtils.toURI(unit);
TextDocumentIdentifier textDocument = new TextDocumentIdentifier(uri);
FormattingOptions options = new FormattingOptions(4, true);// ident == 4 spaces

DocumentOnTypeFormattingParams params = new DocumentOnTypeFormattingParams(textDocument, options, new Position(5, 41), "\n");

preferences.setJavaFormatOnTypeEnabled(true);
List<? extends TextEdit> edits = server.onTypeFormatting(params).get();
assertNotNull(edits);

//@formatter:off
String expectedText =
"package org.sample;\n"
+ "\n"
+ "public class Baz {\n"
+ " public String print() {\n"
+ " int a = 1;\n"
+ " return String.format(\"Value: {}\",\n"
+ " a);\n"
+ " }\n"
+ "}";
//@formatter:on

String newText = TextEditUtil.apply(unit, edits);
assertEquals(expectedText, newText);
}

@Test
public void testDisableFormattingOnType() throws Exception {
//@formatter:off
Expand Down

0 comments on commit 7160575

Please sign in to comment.