我在这方面玩得很开心,在这个过程中学到了很多东西!看起来这里有一些问题。
这是我如何使其工作的方法,尽管由于 vim 有很多方法,因此可能有一种更整洁的方法。
g 命令的格式为 g/pattern/command。我认为发生的事情是你原来的形式,| 新 | 放一个| %s... 该命令的一部分是使用 g 命令逐行执行的,而不是作为 TagSearch 命令的一部分执行一次。我将 g 命令更改为“执行”而不是解决问题 - 我很想知道是否有一种方法可以在不使用执行的情况下指定管道适用的内容,我无法让它工作(括号不起作用例如)。这就是为什么你只得到第一行的原因。这给了我们(修正你的 '%s' 命令中的错字):
command! -nargs=1 TagSearch execute 'g/^\(.\+\n\)\{-}.*#<args>.*/y a' | vnew | put a | %s/^.*#<args>.*\n/&\r
不过,这似乎扭转了问题,我们现在只得到新缓冲区中的最后一行。g 命令的另一个问题是,当您执行 /ya 时,它每次都会覆盖 a 寄存器。有一种方法可以让 vim 使用大写的寄存器名称 (/y A) 代替附加到寄存器(参见 :help quotea)。这样做我们需要先使用 let 将寄存器初始化为空白。这给了我们这个:
command! -nargs=1 TagSearch let @a='' | execute 'g/^\(.\+\n\)\{-}.*#<args>.*/y A' | vnew | put a | %s/^.*#<args>.*\n/&\r
最后,为了让它使用多个标签执行,我只是摆弄<args>
了一下(调用 TagSearch tag1 tag2,args 实际上是字符串'tag1 tag2')以使其适合正则表达式,如下所示:
command! -nargs=* TagSearch let @a='' | execute 'g/^\(.\+\n\)\{-}.*#\(' . substitute('<args>', ' ', '\\|', 'g') . '\).*/y A' | vnew | put a | execute '%s/^.*#\(' . substitute('<args>', ' ', '\\|', 'g') . '\).*\n/&\r'
如果您为此添加更多功能,您可能想尝试使用一些 vimscript 函数或其他东西,否则可能很难维护!您将能够将文本块抓取到漂亮的列表中,并可能更轻松地处理它们,而不必像实际打字一样做所有事情。查看 :help 功能,了解可用的东西(尽管其他地方的 vimscript 帮助可能有更好的起点)。