Vim 奇怪地自动缩进 xml

Vim auto-indenting xml strangely

在 vim (neovim) 中,XML 代码在将属性放在自己的行上时出现奇怪的缩进,如下所示:

<test
    first="text"
    second="more text"
    third="last">
<foo
    a="a"
    b="b">
<bar />
</foo>
</test>

当我期待和渴望时:

<test
    first="text"
    second="more text"
    third="last">
    <foo
        a="a"
        b="b">
        <bar />
    </foo>
</test>

这对我来说感觉像是 none 而不是错误。我找不到解决这个问题的插件。也许我可以在我的 init.vim 中添加一些东西来纠正这种行为?

编辑: 下面的补丁几乎修复了这个问题,但没有正确处理以下情况:

<test
    first="text"
    second="more text"
    third="last">
    <foobar>
    </foobar>
    <foobar>
    </foobar>
</test>

编辑 2: 删除第 90 行的 + shiftwidth() 可以解决所有问题,但这种情况除外:

<test
    first="text">
    <foobar>
    </foobar>
</test>

<foobar>应该如上缩进,因为横跨前两行的标签是开始标签,表示接下来的行应该缩进。

编辑 3:出于某种原因,<foo 在补丁中缩进了两次。预期:

<test>
    <foo
        a="a">
    </foo>
</test>

我对正则表达式的了解足以使用它,但是 vim 脚本让这变得棘手。

编辑 4: 预期输出应为:

<test>
    <foo
        a="a" />
    <foobar
        a="a" >
        <test>
        </test>
    </foobar>
</test>

/> 不应缩进下一行。

我对 XML 的了解不够,无法确定它是否是预期的行为,也无法进行适当的测试,所以我不知道我的解决方案是否是最好的。

但如果您怀疑它是一个错误,那么最好的行动是在 XML 的官方 GitHub 存储库中报告1 它运行时文件:chrisbra/vim-xml-runtime.


我通过应用此补丁成功获得了您的预期结果2:

@@ -81,11 +81,16 @@
 endfun

 " [-- return the sum of indents of a:lnum --]
-fun! <SID>XmlIndentSum(line, style, add)
+fun! <SID>XmlIndentSum(line, style, add, ...)
     if <SID>IsXMLContinuation(a:line) && a:style == 0 && !<SID>IsXMLEmptyClosingTag(a:line)
         " no complete tag, add one additional indent level
         " but only for the current line
         return a:add + shiftwidth()
+    elseif a:0 && a:line =~ '^\s*<[^/]' && a:1 =~ '^\s*<[^/]' && a:1 !~ '>\s*$'
+                \ && getline(prevnonblank(a:2-1)) !~ '/\s*>\s*$'
+        return a:add + shiftwidth()
+    elseif a:0 && a:line =~ '^\s*</' && a:1 =~ '^\s*<' && a:1 !~ '>\s*$'
+        return a:add
     elseif <SID>HasNoTagEnd(a:line)
         " no complete tag, return initial indent
         return a:add
@@ -156,7 +161,7 @@
     " Get indent from previous tag line
     let ind = <SID>XmlIndentSum(pline, -1, pind)
     " Determine indent from current line
-    let ind = <SID>XmlIndentSum(curline, 0, ind)
+    let ind = <SID>XmlIndentSum(curline, 0, ind, pline, a:lnum)
     return ind
 endfun

只需将 indent file 复制到 ~/.vim/indent/xml.vim 3 并应用更改。


1你可以link这个问题中的答案
2 质量只是 临时 hack
3 我相信在 Neovim 的情况下 $XDG_CONFIG_HOME/nvim/indent/xml.vim