507
votes

I've got some Java code with SQL statements written as Java strings (please no OR/M flamewars, the embedded SQL is what it is - not my decision).

I've broken the SQL statements semantically into several concatenated strings over several lines of code for ease of maintenance. So instead of something like:

String query = "SELECT FOO, BAR, BAZ FROM ABC WHERE BAR > 4";

I have something like:

String query =
    "SELECT FOO, BAR, BAZ" +
    "  FROM ABC          " +
    " WHERE BAR > 4      ";

This style makes the SQL much easier to read and maintain (IMHO), especially for larger queries. For example, I can put my editor into "overwrite" mode and modify the text in-place fairly easily.

Note that this issue generalizes beyond the particular example of SQL. Any code that is written with any vertical formatting, particularly tabular constructs, is susceptible to destruction by a pretty printer.

Now, some project members use the Eclipse editor and the semantic formatting is often destroyed when they format an entire source file.

Is there a way to instruct Eclipse to ignore certain lines of source with respect to formatting?

I'm looking for something like a special comment that toggles the Eclipse formatter. Ideally, such a comment could be configurable to be whatever we choose, and other formatters could be programmed to respect it as well:

// STOP-ECLIPSE-FORMATTING
String query =
    "SELECT FOO, BAR, BAZ" +
    "  FROM ABC          " +
    " WHERE BAR > 4      ";
// START-ECLIPSE-FORMATTING

Obviously, one "solution" is to have our team members standardize on some external formatter like Jalopy or JIndent, but that's not what this question is about (also, not my decision on this project): I'm specifically looking for a way to avoid the Eclipse formatter on an ad-hoc basis.

Ideally, a solution will allow me to insert instructions for the Eclipse formatter without requiring team members using Eclipse to do any IDE reconfiguration (other than possibly choosing a formatter agnostic command comment: STOP-ECLIPSE-FORMATTINGSTOP-FORMATTING).

13
We've had this problem. Eclipse should have an option to always break a line in a String constructor where a + is, regardless of whether the next bit of string would fit on the line. But it doesn't. :-(JeeBee
Apparently this feature was added in Eclipse 3.6M6: bugs.eclipse.org/bugs/show_bug.cgi?id=27079Guillaume
Note: If you simply want to prevent eclipse from messing up your comments, then you can use // in front of each line. To comment out a block, highlight and press Ctrl+/.John Henckel
Note that now 10 years later, Java 14 will probably bring multi-line strings making this a thing of the past.Thorbjørn Ravn Andersen

13 Answers

889
votes

Eclipse 3.6 allows you to turn off formatting by placing a special comment, like

// @formatter:off
...
// @formatter:on

The on/off features have to be turned "on" in Eclipse preferences: Java > Code Style > Formatter. Click on Edit, Off/On Tags, enable Enable Off/On tags.

It's also possible to change the magic strings in the preferences — check out the Eclipse 3.6 docs here.

More Information

Java > Code Style > Formatter > Edit > Off/On Tags

This preference allows you to define one tag to disable and one tag to enable the formatter (see the Off/On Tags tab in your formatter profile):

enter image description here

You also need to enable the flags from Java Formatting

62
votes

AFAIK from Eclipse 3.5 M4 on the formatter has an option "Never Join Lines" which preserves user lines breaks. Maybe that does what you want.

Else there is this ugly hack

String query = //
    "SELECT FOO, BAR, BAZ" + //
    "  FROM ABC"           + //
    " WHERE BAR > 4";
32
votes

See this answer on SO.

There is another solution that you can use to suppress the formatting of specific block comments. Use /*- (note the hyphen) at the beginning of the block comment, and the formatting won't be affected if you format the rest of the file.

/*-
 * Here is a block comment with some very special
 * formatting that I want indent(1) to ignore.
 *
 *    one
 *        two
 *            three
 */

Source: Documentation at Oracle.

29
votes

Instead of turning the formatting off, you can configure it not to join already wrapped lines. Similar to Jitter's response, here's for Eclipse STS:

Properties → Java Code Style → Formatter → Enable project specific settings OR Configure Workspace Settings → Edit → Line Wrapping (tab) → check "Never join already wrapped lines"

Save, apply.

enter image description here

16
votes

You have to turn on the ability to add the formatter tags. In the menubar go to:

Windows Preferences Java Code Style Formatter

Press the Edit button. Choose the last tab. Notice the On/Off box and enable them with a checkbox.

14
votes

If you put the plus sign on the beginning of the line, it formats differently:

String query = 
    "SELECT FOO, BAR, BAZ" 
    +    "  FROM ABC"           
    +    " WHERE BAR > 4";
6
votes

End each of the lines with a double slash "//". That will keep eclipse from moving them all onto the same line.

5
votes

I'm using fixed width string-parts (padded with whitespace) to avoid having the formatter mess up my SQL string indentation. This gives you mixed results, and won't work where whitespace is not ignored as it is in SQL, but can be helpful.

    final String sql = "SELECT v.value FROM properties p               "
            + "JOIN property_values v ON p.property_id = v.property_id "
            + "WHERE p.product_id = ?                                  "
            + "AND v.value        IS NOT NULL                          ";
4
votes

Alternative method: In Eclipse 3.6, under "Line Wrapping" then "General Settings" there is an option to "Never join already wrapped lines." This means the formatter will wrap long lines but not undo any wrapping you already have.

4
votes

@xpmatteo has the answer to disabling portions of code, but in addition to this, the default eclipse settings should be set to only format edited lines of code instead of the whole file.

Preferences->Java->Editor->Save Actions->Format Source Code->Format Edited Lines

This would have prevented it from happening in the first place since your coworkers are reformatting code they didn't actually change. This is a good practice to prevent mishaps that render diff on your source control useless (when an entire file is reformatted because of minor format setting differences).

It would also prevent the reformatting if the on/off tags option was turned off.

2
votes

The phantom comments, adding // where you want new lines, are great!

  1. The @formatter: off adds a reference from the code to the editor. The code should, in my opinion, never have such references.

  2. The phantom comments (//) will work regardless of the formatting tool used. Regardless of Eclipse or InteliJ or whatever editor you use. This even works with the very nice Google Java Format

  3. The phantom comments (//) will work all over your application. If you also have Javascript and perhaps use something like JSBeautifier. You can have similar code style also in the Javascript.

  4. Actually, you probably DO want formatting right? You want to remove mixed tab/space and trailing spaces. You want to indent the lines according to the code standard. What you DONT want is a long line. That, and only that, is what the phantom comment gives you!

0
votes

Not so pretty but works with default settings and for the first line as well:

String query = "" +
    "SELECT FOO, BAR, BAZ" +
    "  FROM ABC          " +
    " WHERE BAR > 4      ";
-3
votes

This hack works:

String x = "s" + //Formatter Hack
    "a" + //
    "c" + //
    "d";

I would suggest not to use the formatter. Bad code should look bad not artificially good. Good code takes time. You cannot cheat on quality. Formatting is part of source code quality.