如何格式化代码(自动插入换行符,缩进等)?


24

我正在使用,spacemacs但大概这里需要emacs知识。

我有一个带有长行的JSON文件,让我们说这个来自json.org/example的JSON:

{"menu": {"id": "file", "value": "File", "popup": {"menuitem": [{"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"}]}}}

我希望emacs重新缩进,这对我来说意味着不要将行的最左字符更改为适当的缩进级别,而是将行分成几行。

如果使用spacemacs/indent-region-or-bufferSPC j =),则文本完全不会更改。

我怎么能要求emacs打破这条漫长的路线并重新缩进以获得这样的东西:

{"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}

我对特定于JSON的答案不感兴趣,例如,我相信intelliJ会针对其支持的任何语言(java,json ...)执行此操作。我认为对于任何一种语言,emacs都可以采用一种主要的模式,或者说最受欢迎的语言来实现。

EDIT我发现M-x json-reformat-regionspacemacs随带并可以工作,但是是的,我希望这种语言适用于任何语言,并且基于主要模式始终具有相同的快捷方式...

EDIT2好吧,我的结论是,它至少适用于多种语言,包括JSON和lis​​p,可能还适用于其他语言,并且对其他语言(XML / XHTML,具有go-fmt的go,也使用clang)很容易实现。但是,没有通用函数名称可以对所有语言进行处理。这里有空间可以spacemacs针对各种语言分层实现它……但是我没有找到X / HTML实现,这让我有些惊讶。


3
对于HTML / JS / CSS :web-beautiful.el。这是我发现的最好的,但是取决于node.js。
保姆2015年

Answers:


10

看起来您fill-region比缩进更需要该功能。

  • 选择该行并执行M-x fill-region
  • 选择相同的内容,现在将其分成多行,然后执行M-x indent-region

但是,这不会在示例中所示的确切位置插入新行。它只会使线适合填充列。


1
好吧,那是什么。也许我想要的还是无法实现的。也许我会再等一会,以防有人为神奇的主动缩进提供了一种神奇的解决方案...如果没有其他问题,我将标记为答案。
伊曼纽尔·图泽里

@EmmanuelTouzery只要插入换行符的规则是一致的,您就可以轻松实现任何所需的操作。在格式化后的结果的例子,我看到你没有一个换行符后{{"menu":,但你必须一个接一个{{"id":。我不知道JSON,因此您格式化的答案可能确实有我所缺少的模式。但是,如果您可以使用插入新行的一组规则来更新您的问题,那么有人可以提出您想要的答案。
Kaushal Modi

我认为对于任何一种语言,包括特定于语言的规则,都应该存在。例如,{在Java的第一行上,在C#的下一行上,以此类推。
伊曼纽尔·图扎里

(换句话说,gofmt除了任何语言之外,都类似)-gofmt.com
伊曼纽尔·图泽

19

json.el包提供json-pretty-print-buffer。这是您的示例产生的结果:

{
  "menu": {
    "popup": {
      "menuitem": [
        {
          "onclick": "CreateNewDoc()",
          "value": "New"
        },
        {
          "onclick": "OpenDoc()",
          "value": "Open"
        },
        {
          "onclick": "CloseDoc()",
          "value": "Close"
        }
      ]
    },
    "value": "File",
    "id": "file"
  }
}

对我来说似乎很体面。


2
是的,实际上我在github.com/gongo/json-reformat上看到“从emacs 24.4起,json-pretty-print并且json-pretty-print-buffer(与相似的规范json-reformat-region)捆绑在一起。”。但是我认为emacs可以具有适用于所有语言的功能(特定于每种流行的主要模式语言),事实证明,事实并非如此。
伊曼纽尔·图扎里

这是正确的答案
Joe Heyming

6

根据此处的提示,您可以使用外部命令来格式化Json文件中的区域:

(defun json-format ()
  (interactive)
  (save-excursion
    (shell-command-on-region (region-beginning)
                             (region-end)
                             "python -m json.tool"
                             (buffer-name)
                             t)))

您可以轻松扩展它以格式化整个缓冲区:

(defun json-format ()
  (interactive)
  (save-excursion
    (shell-command-on-region (point-min)
                             (point-max)
                             "python -m json.tool"
                             (buffer-name) t))) 

Emacs没有用于编程语言的格式化工具(Lisp除外),只有缩进命令。


1
我发现M-x json-reformat-regionspacemacs随带并可以工作,但是,是的,我希望对任何一种语言都具有相同的快捷方式,并且基于主要模式……似乎不支持此操作,太糟糕了……
Emmanuel Touzery

1
要正确格式化一种语言,您需要一个实际的语言解析器。Emacs具有某些语言的内置语言解析器,但最近只有内置的Lisp解析器用于代码重新格式化,这是上面的演示的链接。如果存在外部格式化程序,则很容易与Emacs集成,即clang-format
Tu Do

2

对于这种特定情况,json-pretty-print将美化突出显示的json块。


1

顺便说一句,对于使用SMIE作为其缩进引擎的主要模式,您需要以auto-fill-mode支持的形式来完成某些工作。我认为fill-paragraphfill-region做得不好,但是如果您将代码放在一行上,那么请转到该行的末尾,这样做M-: (smie-auto-fill)应该会给出合理的结果(很长一段时间可能并不完美)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.