11

我现在正在编辑一些具有某种结构的 XML 文件,例如:

<Parent>
  <Child name="Fred">
    Some content
  </Child>
  <Child name="George" value="other content" />
  ...
</Parent>

换句话说,某些父元素的内容将是一系列子元素(在这种情况下具有相同的名称)。例如,想想目录中的待售物品列表,甚至<xsl:template><xsl:stylesheet>.

当我在父元素中时,我想做的是在vim中映射一些键序列以转到下一个(或上一个)子元素,并且理想情况下能够用一个计数作为前缀(这样我就可以“去到下一个孩子的第五个,例如)。理想情况下,我需要在 Child 元素的内容之外才有意义,这样在 Child 元素内我可以使用相同的地图在 Grandchildren 之间跳转。我在网上寻找插件/解决方案,但没有找到任何东西。

我目前可以做的是vat<Esc>j在下一个孩子在这个孩子关闭后的下一行的情况下(vato<Esc>k与前面的孩子类似)。但是,我对此有一些问题:

  1. 我不能在这个前面加上一个计数;在映射导致奇怪行为之前这样做(请参阅:help v,以 count 为前缀v不会做我想要的);在映射(例如 v2at)中这样做会连续选择“更高”的封闭元素。
  2. 如果子元素的序列不紧跟在彼此之后,这将不起作用,每个开始标签紧跟在前一个结束标签的下一行。
  3. 如果我在父级的最后一个子级上执行此操作,我将转到父级的结束标记(或者它的一些文本内容,如果它存在,或者其他)
  4. 破坏先前选择的区域

数字 2 并不是非常重要——我可能可以对正在编辑的文件强制执行正确的格式设置,并且可以使用 xmllint 轻松完成此操作。如果可能的话,我仍然更喜欢更“语义”的优雅和健壮性方法。3 号真的没什么大不了的,如果我可以留在原地,或者去第一个孩子,当最后一个孩子时,这将是一个不错的奖励。4号对我来说根本不是问题。也许它会干扰插件,或者我将来的工作,但无论如何,肯定不是关键。

1 号是关键,因为我经常发现自己想要让这么多孩子失望。目前,我正在寻找我想去的孩子,看了一眼我那条线的 relativenumber,然后向下(或向上)移动那么多行。这是

  • 烦人,而且我对 XML 内容的看法并不明显
  • 不容易编写脚本/宏,至少不是健壮的

另一种可能的解决方案是搜索Child然后去[count]nor [count]N。这也有几个问题:

  1. 要么我必须自己考虑并输入名称Child,这完全不可编程;或者我做一些vato<Esc>l*不能以我想要的方式以计数作为前缀的事情
  2. Child当元素相互嵌套时中断(有用例),将Child元素拆分为单独Parent的元素,当字符串"Child"出现在除Child元素之外的任何位置时等。
  3. 破坏以前的搜索;当我使用搜索来突出显示当前相关的内容,或者在跳转到下一个元素后仍希望能够跳转到下一个搜索项时,这很麻烦。

理想情况下,我会创建某种函数+命令+映射,以稳健、智能的方式处理所有这些。然后我可以在编辑时盲目地使用我的命令,并且在尝试记录通过在元素之间跳转等工作的宏时不会感到头疼。但是,我对 vimscripting 还是很陌生,不太确定如何开始。

4

3 回答 3

3

它们显然不能满足您的所有要求,但这些粗略的命令可能会有所帮助……</p>

/^\s\{<C-r>=indent(".")<CR>}<\w\+\s<CR>
?^\s\{<C-r>=indent(".")<CR>}<\w\+\s<CR>

向前/向后跳转到相同缩进级别的下一个 XML 标记。

于 2013-10-16T19:41:21.010 回答
2

如果您经常需要此动作,则为其创建自定义动作是有意义的。使用我的CountJump 插件,这很容易:

call CountJump#Motion#MakeBracketMotion('<buffer>', '', '', '<Child', '<Child.*\zs/>\|</Child>', 0)

这将修改[[ []等动作(您也可以选择其他映射),并且也支持计数。(将其放入例如~/.vim/ftplugin/xml_motions.vim。)

于 2013-10-17T07:07:15.000 回答
2

let g:xml_syntax_folding = 1我可能只是调整折叠(您可以使用and打开 XML 折叠setlocal foldmethod=syntax),以便子元素全部折叠(例如zMzr)。然后,导航到 childs 是一个简单的“N line(s) up/down” with j/ k

于 2013-10-17T06:59:54.863 回答