如何使用Vim跳转到XML元素的下一个兄弟?

时间:2013-10-16 17:29:20

标签: xml vim

我现在编辑了许多XML文件,这些文件具有某种结构,如:

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

换句话说,某些父元素的内容将是一系列子元素(在本例中具有相同的名称)。例如,考虑目录中的待售商品列表,甚至是<xsl:template><xsl:stylesheet>的序列。

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

我可以做的是vat<Esc>j,如果下一个Child在这个Child关闭后的下一行(类似vato<Esc>k前一个Child)。但是,我有一些问题:

  1. 我不能用计数加上前缀;在映射之前执行此操作会导致奇怪的行为(请参阅:help v,在v前加上计数并不会执行我想要的操作);在映射中执行此操作(例如v2at)会连续选择“更高”的封闭元素。
  2. 如果子元素的序列不是直接跟在彼此之后,那么这将不起作用,每个开始标记紧跟前一个结束标记的下一行。
  3. 如果我在父母的最后一个孩子身上这样做,我会转到父母的结束标签(或者它的一些文本内容,如果它存在,或者其他)
  4. Clobbers先前选定的地区
  5. 数字2并不是非常关键 - 我可以对我正在编辑的文件强制执行正确的格式化,并且可以使用xmllint轻松完成此操作。如果可能的话,我仍然希望采用更“语义”的方法来实现优雅和稳健。 3号真的不是什么大不了的事,如果我可以留在原地,或者去第一个孩子,最后一个孩子,这将是一个很好的奖励。 4号对我来说还没有问题。也许它会干扰插件,或者我将来的工作,但无论如何,当然不是关键。

    然而,数字1是关键的,因为我经常发现自己想要让这么多的孩子失望。目前,我正在寻找我想去的孩子,瞥一眼我那条线的相对数字,然后往下走(或向上)。这是

    • 烦人,而且我对XML内容的思考方式并不明显
    • 不易编写脚本/宏,但至少不够健壮

    另一种可能的解决方案是搜索Child,然后转到[count]n[count]N。这也有一些问题:

    1. 要么我必须考虑并自己输入名称Child,这完全不可编程;或者我做vato<Esc>l*之类的事情,不能以我想要的方式作为计数前缀
    2. Child个元素嵌套在彼此内部(具有用例)时,如果字符串Child出现在除{as}之外的任何位置,则将Parent元素拆分为不同的"Child"元素时中断一个Child元素等。
    3. Clobbers以前的搜索;当我使用搜索来突出显示当前相关的内容时,或者仍然希望能够在跳转到下一个元素后跳转到下一个搜索项目时,这会令人讨厌。
    4. 理想情况下,我会创建某种函数+命令+映射,以强大,智能的方式处理所有这些。然后我可以在编辑时盲目地使用我的命令,并且没有头痛试图记录一个通过跳转元素等工作的宏。但是,我仍然很新的vimscripting并且我不太确定如何开始。

3 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:2)

我可能只是调整折叠(您可以使用let g:xml_syntax_folding = 1setlocal foldmethod=syntax打开XML折叠),以便子元素全部折叠(例如zMzr)。然后,使用j / k向儿童导航是一个简单的“N行上/下”。

答案 2 :(得分:2)

如果您经常需要此动作,则为其创建自定义动作是有意义的。使用我的CountJump plugin,这非常简单:

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

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