如何关闭Eclipse代码格式化程序以针对Java代码的某些部分?

527

我有一些Java代码,其中包含作为Java字符串编写的SQL语句(请不要进行ORM争论,嵌入式SQL就是它本来的样子 - 不是我的决定)。

出于维护方便的考虑,我将SQL语句在代码中按语义分成了几个连接的字符串。因此,代码不是这样的:

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

我有这样的东西:

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

在我看来,使用这种风格可以使SQL更易于阅读和维护,尤其是对于较大的查询。例如,我可以将编辑器设置为“覆盖”模式,并相当轻松地就地修改文本。

请注意,这个问题不仅限于特定的SQL示例。任何用任何垂直格式编写的代码,特别是表格式结构,都容易被美化器破坏。

现在,一些项目成员使用Eclipse编辑器,当他们格式化整个源文件时,语义格式经常会被破坏。

是否有一种方法可以指示Eclipse忽略某些源行以实现格式化?

我正在寻找像一个特殊注释那样可以切换Eclipse格式化程序的东西。理想情况下,这样的注释可以配置为我们选择的任何内容,并且其他格式化程序也可以编程以尊重它:

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

显然,一种“解决”方法是让我们的团队成员采用一些外部格式化工具(如JalopyJIndent)进行标准化,但这不是本问题的重点(在这个项目中也不是我的决定):我特别寻找一种避免以临时方式使用Eclipse格式化程序的方法。

理想情况下,一种解决方案将允许我插入Eclipse格式化程序的指令而不需要要求使用Eclipse的团队成员进行任何IDE重新配置(除了可能选择一个格式化程序不可知的命令注释:STOP-ECLIPSE-FORMATTINGSTOP-FORMATTING)。


1
我们遇到了这个问题。Eclipse 应该有一个选项,可以在字符串构造函数中始终在+处断行,而不管下一部分字符串是否适合在该行上。但它没有。 :-( - JeeBee
显然,这个功能是在Eclipse 3.6M6中添加的:https://bugs.eclipse.org/bugs/show_bug.cgi?id=27079 - Guillaume
注意:如果您只是想防止Eclipse破坏您的注释,那么可以在每行前面使用//。要注释掉一个块,请将其突出显示并按Ctrl + /。 - John Henckel
请注意,现在已经过去了10年,Java 14可能会引入多行字符串,使得这种情况成为过去。 - Thorbjørn Ravn Andersen
1
文本块自Java 15起可用,适用于像这样的SQL查询。请参见http://openjdk.java.net/jeps/378 - user18619318
14个回答

922

Eclipse 3.6允许您通过放置特殊注释来关闭格式化,例如:

// @formatter:off
...
// @formatter:on
在Eclipse首选项中需要打开“开/关”功能:Java > Code Style > Formatter,然后单击EditOff/On Tags并启用Enable Off/On tags
还可以在首选项中更改魔法文本字符串。请查看Eclipse 3.6文档这里
更多信息: Java > Code Style > Formatter > Edit > Off/On Tags 此首选项允许您定义一个标记以禁用格式化程序,另一个标记以启用它(请参见格式化程序配置文件中的“Off/On Tags”选项卡): enter image description here 您还需要启用Java Formatting标志。

7
此页面其他地方提到的"Never join lines"选项也非常有用。 - xpmatteo
94
在Eclipse首选项中,找到Java > 代码样式 > 格式化器。点击“编辑”按钮,然后在“开/关标签”下勾选“启用开/关标签”,这样才能打开“开/关”功能。注意不改变原意,使语言更加通俗易懂。 - Domenic D.
2
这在 JavaScript 代码样式偏好设置 中不可用,我在格式设置方面遇到了完全相反的问题,很遗憾。 :( - Redsandro
14
团队应该将Eclipse Prefs(文件)的副本导出到他们的Wiki上,并要求每个人都使用相同的文件。这对我们很有效。 ;) - Joseph Lust
1
非常感谢!当使用maven-formatter-plugin时也可以这样做(我在格式化程序xml文件中手动更改了设置org.eclipse.jdt.core.formatter.use_on_off_tags)。 - nuoritoveri
显示剩余3条评论

63

据我所知,从Eclipse 3.5 M4版本开始,格式化程序有一个选项叫做“永不合并行”,该选项可以保留用户的换行符。也许这正是您想要的。

否则,还有这个丑陋的技巧。

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

1
所以除了设置“永不合并行”选项外,我还必须编写这些“幽灵”注释吗?“永不合并行”的部分本身就应该起作用,不是吗? - Greg Mattes
2
当然应该。幽灵评论是一种替代方法(在它不存在或者你被困在早期版本中时等情况下)。 - Chris
我曾经将这种方法与 TOAD 中的自定义格式模板配合使用,以使我能够从 JAVA 代码中剥离旧的 SQL,重新格式化并获取所有多余的注释,然后将其放回到 JAVA 中。虽然麻烦,但现在我们已经可以在保存 Java 代码时自动进行格式化。感谢您的建议! - jnt30
没有勾选“永不合并行”时,我的开/关宏无法正常工作 - 谢谢! - Christoffer Soop

40

SO上的这个答案

还有另一种解决方案,可以用来抑制特定块注释的格式。在块注释开头使用/*-(注意连字符),如果你对文件的其余部分进行格式化,格式不会受到影响。

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

来源: Oracle文档.


5
这是最好的答案,因为它不依赖于用户IDE的配置。谢谢。 - Azim

31

不需要关闭格式化,你可以配置它不要加入已经换行的行。类似于Jitter的响应,这是针对Eclipse STS的:

属性→ Java代码风格→ 格式化程序→ 启用项目特定设置或配置工作区设置→ 编辑→ 行包装(选项卡)→ 选中“永远不加入已经换行的行”

保存,应用。

输入图像描述


1
我认为这对于像SQL示例这样的东西会有所帮助,但我不确定它是否足以完全禁用IDE格式化程序的一般情况。 - Greg Mattes
4
在使用生成器模式时,这种解决方案非常出色,并且随着Java 8中Lambda的引入,它的相关性无疑得到了增强。 - Jonas Kongslund
这也适用于格式化Java流函数,如map->filter->reduce。 - Abdullah Khan

16

您需要开启添加格式化标签的功能。在菜单栏中前往:

Windows Preferences Java Code Style Formatter

点击Edit按钮,选择最后一个选项卡。注意到开关按钮并用复选框启用它们。


14

如果您将加号放在行的开头,则格式会有所不同:

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

1
这可能是一个有趣的妥协。总的来说,由于某些工具的不良行为,我希望尽量避免过多改变代码的格式。在这种情况下,字符串连接操作符更像是偶然而非 SQL 进行的本质。这就是为什么我更喜欢将它们写在每行的末尾。我觉得 SQL 应该作为行首突出显示。但如果没有让我保留所需格式的解决方案,这可能是一个不错的选择。谢谢! - Greg Mattes
8
不客气。实际上,我已经将加号放在行首数十年了,并非为了欺骗格式化程序。我更喜欢将它们放在行首,因为这可以让我更清楚地看到发生了什么:有时候行末的内容会丢失。这是很久以前我们使用木制编译器时的项目标准,而我一直保留着这个习惯。 - CPerkins

6

在每行结尾加上双斜杠“//”。这样可以防止Eclipse将它们全部移动到同一行。


4

我正在使用固定宽度的字符串部分(用空格填充)来避免格式化程序破坏我的SQL字符串缩进。这会给你带来混合的结果,并且在不忽略空格的情况下无法正常工作,但是可以有所帮助。

    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

@xpmatteo有禁用代码部分的答案,但除此之外,应将默认的eclipse设置为仅格式化编辑过的代码行而不是整个文件。

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

这将防止发生代码格式重排却未实际更改的情况,从而避免了因微小格式设置差异导致源代码控制diff无用的意外事件。这是一种良好的实践方法。如果关闭on/off标记选项,也可以防止重新格式化。

4

另一种方法:在Eclipse 3.6中,在“换行”下,然后是“常规设置”,有一个选项“永不加入已经换行的行。”这意味着格式化程序将换行长行,但不会撤消您已经拥有的任何换行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接