Vim缩进XML文件

123

我正在学习Vim,但我认为这是一项简单任务,但我无法使其正常工作。我已经在Stack Overflow上查找了解决方案,但它们对我无效。

我正在尝试正确地缩进一个文件(xml)。我使用的命令是:

gg=G 

或者 ggVG=(我自己想出来的,可能会有不同的效果;)

我的 .vimrc 文件如下:

syntax on 
filetype plugin indent on 
set nu 

原始输入、结果和期望输出是什么? - Ingo Karkat
:set ft? indentexpr? 的输出是什么?它是否读取 filetype=xml indentexpr=XmlIndentGet(v:lnum,1) ?! - Ingo Karkat
文件类型=xml 缩进表达式=XmlIndentGet(v:lnum,1)。没错。 - Haagenti
1
请参见 https://dev59.com/F2gu5IYBdhLWcg3wAici。 - user539810
1
我想在这个映射中添加一点内容,使其变为m'ggVG='',它可以保存当前行的位置,在重新缩进文件后返回到该行。 - Hovis Biddle
显示剩余2条评论
10个回答

244

我喜欢Berei的答案。不过,我认为以下方法更加灵活,因为您无需更改vimrc文件。而且更容易格式化所选部分的XML文件(这是我经常做的事情)。

首先,突出显示要格式化的XML。

然后,在可视模式下,键入!xmllint --format -

底部的命令行将如下所示:

:'<,'>! xmllint --format -

然后按回车键。

技术解释

所选文本被发送到xmllint命令,然后进行--format操作,并且xmllint的结果被放置在vim中您选择的文本上方。命令末尾的-用于接收标准输入流,即此处vim发送给xmllint的所选文本。


6
当然,这只在您安装了外部工具xmllint并将其添加到系统路径中时才有效。 - Polymorphix
86
为了简化命令,:%!xmllint --format -% 表示整个 XML 文件范围。 - hakunami
2
为什么每个人都期望有一个 xmllint 工具呢?在 Ubuntu 15.04 中并没有这个工具,apt-get 也找不到。 - erikbstack
9
在搜索软件包和软件包内容时,请使用“apt-cache search”而不是“apt-get”。 “libxml2-utils”包含所需的工具。 - ParanoiaPuppy
1
为什么不使用标准的vim格式化方式呢?通过smartindent和filetype,它可以在没有外部依赖的情况下工作。 - Krzysztof Krasoń
显示剩余5条评论

79

使用外部程序对您的 xml 文件进行缩进。在这种情况下,我选择了 xmllint,因此将命令设置为 equalprg 选项:

:set equalprg=xmllint\ --format\ -

现在您可以执行

gg=G

xmllint格式化您的xml文件。

要在每次使用时都使用它,请使用autocommand进行设置。

autocommand参见下面的评论

au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null

1
不确定为什么这个有效,因为我是初学者,但我会弄清楚的 ;) 谢谢,现在它有效了 ;) - Haagenti
11
当你编辑XML文件时,可以在你的.vimrc文件中使用以下内容来启用它:au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null. 出处- http://ku1ik.com/2011/09/08/formatting-xml-in-vim-with-indent-command.html - studgeek
1
非常感谢!由于大型XML文件和vim的问题让我很沮丧,但在Sublime中,它们可以快速重新缩进(包括5000-10000行和base64数据),而在Vim中,却需要几分钟的时间才能重新缩进。这个解决方案解决了大型XML文件的问题。再次感谢Vim。 - Sonique
3
如果您使用的是Ubuntu操作系统,您需要安装libxml2-utils软件包才能获取xmllint。 - hoffmanc

38
一个我喜欢的不需要任何第三方工具的简单解决方案是在每个开放标签“<...>”之前插入一个换行符。然后您可以使用标准vim自动缩进功能。简而言之:
  1. %s/</\r</g
  2. gg=G 自动缩进

我已经尝试了一个很大的XML文件,处理起来非常漫长。 - Luc M
谢谢。这很容易,而且可以完成工作,无需使用外部工具。 - airstrike
10
我更喜欢使用 %s/></>\r</g,这样每个文本元素都保持在同一行。 - Nicola Musatti
3
如果标签之间有时存在空格,可以使用 %s/> *</>\r</g 进行替换。请注意,我会尽最大努力保持原文的意思和表达方式不变,同时使翻译更加通俗易懂。 - Arthur Tacca
它回复“缩进了115行”,但实际上没有缩进。需要设置哪些选项?或者这个方法是否需要我没有的外部依赖? - krubo
可能是您的文件类型设置不正确,krubo。 - KFL

13

简短回答: 打开matchit.vim。您可以在.vimrc中添加packadd matchit,或使用vim-sensible,它默认启用。

详细回答: 我尝试了许多策略来自动缩进Vim中的XML,包括在Vim Wiki上讨论的xmllint方法xmllint(以及其他外部CLI工具,如xmlformattidy)的问题在于它们都坚持挤出空白换行符。如果您只想缩进XML而不删除空行、注释和/或其他有意格式,则xmllint不是最佳选择。

原来Vim的等号(=)命令已经支持XML,只要启用matchit.vim脚本即可。一种超级简单的方法是采用tpope的vim-sensible。另一种方法是在.vimrc中添加packadd matchit。然后,XML格式化将直接“运作”。


1
更准确地说,看起来 matchit.vim 是实际的解决方案。您可以通过添加以下行在您的 vimrc 中启用它:packadd matchit - Christian Rondeau
1
谢谢Christian;我更新了答案以澄清matchit.vim是解决问题的方法。 - ctrueden
因为这个方法对我来说最有效,我点了赞。不过,我建议在简短的答案中加入Christian的建议(packadd matchit),因为它非常简单而且能胜任工作(至少对我是这样)。 - mark sabido
1
@tohuwawohu 使用 = 命令。如果您在文件顶部,可以键入 =G。或者,您可以使用 1G 到达文件顶部,使用 V 进入可视行选择模式,然后键入 G 到达文件底部并选择所有内容。然后按 = 缩进整个文件。同样,如果您只想缩进文件的一部分,请仅选择该部分,然后按 = - ctrueden
1
@tohuwawohu,我刚意识到你说的是“没有任何换行符”。=命令不会插入(或删除)不存在的换行符。它只影响前导缩进。因此,matchit.vim不是将所有挤在一行上的XML格式化的解决方案。请使用xmllint或类似工具进行格式化。 - ctrueden
显示剩余2条评论

11
这很容易实现,只要正确设置~/.vimrc即可。
请在~/.vimrc中设置以下选项:
filetype indent on
set smartindent

使用 gg=G 可以将光标移动到文件顶部并进行自动缩进。

在可视模式下选择所需文本,然后按下 = 键进行缩进。


2
我想应该是 .vimrc 而不是 .bashrc - Birei
1
糟糕。没错,已经修复了。谢谢。 - jarederaj
只有当每个标签都在一行时,这种方法才有效。如果 XML 没有空格或换行符,这种方法将不起作用。 - José Ramón
只要标记有效,它一直对我有效。 - jarederaj
如果你的标记不是在不同的行上,你可以使用 :%s/</\r</g 和 :%s/\n\n/\r/ 来进行松散的更改。 - jarederaj
如果您想要美化您的HTML,您可以使用我之前制作的这个脚本:https://github.com/jarederaj/CleanHTML - jarederaj

9

Jesse Hogan的答案很好,但我更喜欢更简单的答案:

当您在vim中打开XML文件时,在正常模式下写入以下内容:

:%!xmllint --format %

然后按下回车键。您的整个XML文件将被格式化。

请记住,在此之前,您应该已经安装了xmllint


6
在VIM中,使用下面的命令可以对整个文件进行自动缩进(使用硬制表符):
:%!XMLLINT_INDENT="^I" xmllint --format -

^I是一个单字符,你可以通过以下方式生成:CTRL+vCTRL+i


1
我是一位有用的助手,可以为您翻译文本。
我遇到了相同的问题。结果发现,那行代码是:
set viewdir=~\.vim\views\

在我的.vimrc文件中引起了问题。只要确保你没有它。

0

由于某些Java问题,无法使工作。事实证明,使用Python的xml模块可能是一个快速解决方案,因为许多现代系统已经配备了Python。将以下内容添加到您的<.vimrc>

com!FormatXML:%!python3 -c“import xml.dom.minidom,sys; print(xml.dom.minidom.parse(sys.stdin).toprettyxml())”

现在,您可以从命令模式执行:FormatXML。然后使用以下语法突出显示

:set ft=xml
# OR
:set syntax=xml

奖励:由于我是使用SAML进行操作的,您可以通过选择base64文本(可视模式)并在命令模式下执行!base64 -d来快速解码vim / neovim中的base64。 命令如下所示:

:'<,'>!base64 -d


0

对于那些使用 coc.nvim 插件的人,你可以通过 :CocInstall coc-xml 安装 coc-xml。然后在您的配置文件中映射格式键:nmap <silent> fm <Plug>(coc-format)。从现在开始,你可以非常容易地格式化不仅是 XML 文件,还有其他文件。


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