Skip to content

Instantly share code, notes, and snippets.

@samba2
Created December 25, 2019 10:13
Show Gist options
  • Save samba2/7d2f244f4e0d2a6220ac99de570a5221 to your computer and use it in GitHub Desktop.
Save samba2/7d2f244f4e0d2a6220ac99de570a5221 to your computer and use it in GitHub Desktop.
Visual Studio Code Java - Method Chain Formatting

Issue

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:

Is (not good)

var a = a().b().c(new X().y().z()).d();        

Should be (good)

var a = a()
        .b()
        .c(new X()
                .y()
                .z())
        .d();       

Quick Solution

Adjust Formatter Config

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"

Formatting A Chain

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.

Background

VSCode Java uses Eclipse not only for intellisense but also for code formatting.

Never Join Already Wrapped Lines

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.

Extracting The Config

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/'
@tsonev7
Copy link

tsonev7 commented Dec 10, 2020

Thanks for the tip!

You have a typo in the diff command: orginal.xml -> original.xml. :)

@demarcomsevthr
Copy link

The only setting that really fixes is this:
org.eclipse.jdt.core.formatter.join_wrapped_lines=false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment