【问题标题】:VIM: Scripting a selection of the entire CDATA sectionVIM:为整个 CDATA 部分的选择编写脚本
【发布时间】:2012-03-26 13:55:49
【问题描述】:

我正在尝试使用 VIM 选择整个 XML CDATA 部分。对于不熟悉 XML 的人,CDATA 部分如下所示:

<someTag><![CDATA[
This text is escaped in a Character Data section!
Look, I can use < and > characters freely!
]]></someTag>

<anotherTag><![CDATA[More escaped text!]]></anotherTag>

我尝试使用此映射来直观地选择和拉动 CDATA 部分内的文本,但似乎调用函数禁用了视觉选择:

inoremap <F9> <Esc>:call searchpair('<!\[CDATA\[', '', ']]>', 'b')v:call searchpair('<!\[CDATA\[', '', ']]>')y

有没有办法选择整个 CDATA 部分?这是我用来在基于 C 的语言中选择方法的,供参考:

inoremap <F7> <Esc><C-V>aBy

谢谢。

【问题讨论】:

    标签: xml vim cdata


    【解决方案1】:

    这个固定版本适合我

     :inoremap <F9> <Esc>:call searchpair('<!\[CDATA\[', '', ']]>', 'b')<CR>
          v:<C-u>call searchpair('<!\[CDATA\[', '', ']]>')<CR>v`<o
    

    (现实生活中没有换行)

    技巧:

    • &lt;CR&gt; 用于必要的 Enter
    • &lt;C-u&gt; 清除命令行上的范围
    • v` 重新选择到视觉选择的开始
    • o 将光标移动到视觉选择的末尾

    我很惊讶这将是一个插入模式映射,我假设你也有正常模式映射。

    顺便说一句,也许您也会对“正确”文本对象语义的 operator pending 模式映射感兴趣:

    编辑更新以回应评论:

    以下似乎可行(在搜索模式中明智地使用\zs\ze)。您可能想要回溯一个位置(将&lt;BS&gt; 添加到映射的末尾)。另外,到现在为止,operator-pending 类型映射似乎变得更有吸引力了。

    :inoremap <F9> <Esc>:call searchpair('<!\[CDATA\[\zs', '', '\ze]]>', 'b')<CR>
        v:<C-u>call searchpair('<!\[CDATA\[\zs', '', '\ze]]>')<CR>v`<o
    

    PS.:您可能还想在搜索模式中应用明确的魔法级别(例如 \V

    【讨论】:

    • 非常感谢,这是我需要的 99% 的方法!我没有意识到需要&lt;CR&gt; 字符。但是,此映射还会选择前导 &lt;![CDATA[ 文本和一个尾随 ]。如果 CDATA 分隔符在自己的行上,则在适当的位置插入 8l2h 不起作用。有什么办法可以防止这些字符被选中?
    • 谢谢。它仍在捕获[](对于多行和单行CDATA 部分甚至不同),这可以通过xing 选定的文本看到。我现在正在阅读有关运算符挂起类型映射的内容,但我以前从未听说过。谢谢。
    • space(而不是l)和backspace(而不是j)有效吗?他们跨越换行符 IIRC
    • 谢谢。带有&lt;Space&gt; 的单行字符串开头的一个字符不会被复制!我会尝试一些有创意的&lt;Space&gt;ing 和hing,看看能不能得到正确的结果。
    • 回想起来,我真的只需要在多行 CDATA 部分上使用此功能。它可以很好地用于该目的,所以我将保留它,直到我可以学习运算符挂起的类型映射。非常感谢您的帮助!
    【解决方案2】:

    当您制作文本对象时,重要的是不要环绕文件。

    :call searchpair('<!\[CDATA\[', '', ']]>', 'bW')|call searchpair('<!\[CDATA\[', '', ']]>', 'sW')|norm v''o
    

    使用 's' 标志设置 ' 标记,这很好。

    使用 'W' 标志确保我们不进行 EOF 包装,这很重要。

    此外,插入模式映射通常受益于&lt;C-O&gt;,尽管在这种情况下并没有那么多。不过,养成这个习惯是个好习惯。所以:

    :inoremap <F9> <C-O>:<C-U>call searchpair('<!\[CDATA\[', '', ']]>', 'bW')|call searchpair('<!\[CDATA\[', '', ']]>', 'sW')|norm v''o
    

    【讨论】:

    • 谢谢。就像 sese 的代码一样,这个映射从 &lt;![CDATA[]]&gt; 中捕获了 [] 字符。我正在尝试使用它来查看是否可以可靠地删除这些字符。多行 CDATA 部分很麻烦,因为 hl 不能用于简单地移动光标。
    猜你喜欢
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 2013-08-09
    • 1970-01-01
    相关资源
    最近更新 更多