我现在编辑了许多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)。但是,我有一些问题:
:help v
,在v
前加上计数并不会执行我想要的操作);在映射中执行此操作(例如v2at)会连续选择“更高”的封闭元素。数字2并不是非常关键 - 我可以对我正在编辑的文件强制执行正确的格式化,并且可以使用xmllint轻松完成此操作。如果可能的话,我仍然希望采用更“语义”的方法来实现优雅和稳健。 3号真的不是什么大不了的事,如果我可以留在原地,或者去第一个孩子,最后一个孩子,这将是一个很好的奖励。 4号对我来说还没有问题。也许它会干扰插件,或者我将来的工作,但无论如何,当然不是关键。
然而,数字1是关键的,因为我经常发现自己想要让这么多的孩子失望。目前,我正在寻找我想去的孩子,瞥一眼我那条线的相对数字,然后往下走(或向上)。这是另一种可能的解决方案是搜索Child
,然后转到[count]n
或[count]N
。这也有一些问题:
Child
,这完全不可编程;或者我做vato<Esc>l*
之类的事情,不能以我想要的方式作为计数前缀Child
个元素嵌套在彼此内部(具有用例)时,如果字符串Child
出现在除{as}之外的任何位置,则将Parent
元素拆分为不同的"Child"
元素时中断一个Child
元素等。理想情况下,我会创建某种函数+命令+映射,以强大,智能的方式处理所有这些。然后我可以在编辑时盲目地使用我的命令,并且没有头痛试图记录一个通过跳转元素等工作的宏。但是,我仍然很新的vimscripting并且我不太确定如何开始。
答案 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 = 1
和setlocal 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
。)