By default VS Code Java squeezes chained methods into one line. The goal is to have VS Code Java behave similary to IntelliJ: the second and following methods are properly indented but not pulled back to the line which started the method chain.
In short:
var a = a().b().c(new X().y().z()).d();
var a = a()
.b()
.c(new X()
.y()
.z())
.d();
Run this snippet once per project:
cat <<EOF >> .settings/org.eclipse.jdt.core.prefs
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.comment.indent_root_tags=false
org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=true
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=true
org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.jdt.core.formatter.join_wrapped_lines=false
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
org.eclipse.jdt.core.formatter.tabulation.char=space
org.eclipse.jdt.core.formatter.lineSplit=120
EOF
This changes the formatter to preserve new lines when formatting chances. Also it uses "spaces" instead of "tabs"
Manually add a newline character (aka "press Enter") before the method you want to have pushed on a new line. Usually, this is the second method and following. When running the formatter it should leave the broken down methods on their dedicated lines and only adjust their indentation.
VSCode Java uses Eclipse not only for intellisense but also for code formatting.
When looking at the VSCode Java issues formatting method chains is still an ongoing discussion. After some research the second answer of this StackOverflow entry pointed me towards the here presented approach. Basically, it recommends using the formatter config option "Line Wrapping > Never join already wrapped lines" to achieve the desired behaviour.
To make changes to the formatter settings you either understand the verbose config format above (I don't) or use Eclipse to extract those settings (I went for this).
Extracting formatter config from Eclipse:
- open Eclipse
- open Windows > Preferences > Java > Code Style > Formatter
- create a "New" profile named "original"
- when the profile editor is open "Export" to "orignal.xml"
- go back with "Cancel" to the profile chooser
- create again a "New" profile, this time named "fluent"
- in the profile editor
- tick "Line Wrapping" > "Never join already wrapped lines"
- change "Indentation" > "Tab policy:" to "Spaces only" (my personal preference)
- "Export" to "fluent.xml"
Now extract the config changes in the format which can be then pasted into .settings/org.eclipse.jdt.core.prefs
:
diff --changed-group-format='%<' --unchanged-group-format='' fluent.xml orginal.xml | grep 'setting' | sed -E 's/^.+<setting id="(.+)" value="(.+)"\/>/\1=\2/'
Thanks for the tip!
You have a typo in the
diff
command:orginal.xml
->original.xml
. :)