Vim:用于过滤出文本块的多命令

问题描述 投票:1回答:2

这是我对using multi-line regex in Vim的问题的跟进。

快速说明:我有一些用#tags标记并用空白行分隔的文本块。我想过滤掉所有包含特定标签的块。我在这里得到了正则表达式的帮助(谢谢!),所以我构造了以下命令:

command -nargs=1 TagSearch g/^\(.\+\n\)\{-}.*#<args>.*/y a | vnew | put a | %s/^#.*<args>.*\n/&\r 

因此,进行:TagSearch tag应该:

  1. 搜索#tag
  2. all对应的文本块粘贴到新的垂直缓冲区中,
  3. 在新缓冲区的文本块之间添加空白行。

Q1:当我分别执行每个步骤时,一切正常。但是多命令仅粘贴第一个匹配的文本块到新缓冲区中。为什么?

Q2:如何使命令接受多个参数(以防我想一次搜索多个#tags)?谢谢!

regex vim command tagging multiline
2个回答
1
投票

一个人可以使用以下实现。

command! -nargs=* -bar TagSearch call CollectParagraphs([<f-args>])

function! CollectParagraphs(tags) range
    let tags = len(a:tags) > 0 ? a:tags : [expand('<cword>')]
    let pats = map(copy(tags), '"\\.\\*#" . escape(v:val, "\\")')

    let v = winsaveview()
    let [sr, @/; lines] = [@/, '\V' . join(pats, '\&')]
    g//call extend(lines, getline(search('\n\n\zs', 'bnW'), line("'}")))
    let @/ = sr
    call winrestview(v)

    exe 'vnew' escape(join(tags), ' %#|\')
    set buftype=nofile bufhidden=hide noswapfile
    call setline(1, lines)
endfunction

1
投票

我在这方面玩得很好,在此过程中学到了很多!似乎这里有一些问题。

这里是我如何使它正常工作的方法,尽管由于vim有很多方法,所以某种程度上可能会更简洁一些。

g命令的形式为g / pattern / command。我认为发生的事情是您的原始形式, vnew |放一个| %s ...命令的一部分是使用g命令逐行执行的,而不是TagSearch命令的一部分。我将g命令更改为“执行”,从而解决了问题-我很想知道是否有一种方法可以在不使用execute的情况下指定管道所适用的内容,所以我无法使其正常工作(括号不起作用)例如)。这就是为什么只获得第一行的原因。这给了我们(在您的'%s'命令中修正了错字):

command! -nargs=1 TagSearch execute 'g/^\(.\+\n\)\{-}.*#<args>.*/y a' | vnew | put a | %s/^.*#<args>.*\n/&\r

不过,这似乎可以解决问题,现在我们只能在新缓冲区中获得最后一行。 g命令的另一个问题是,当您执行/ y a时,每次都会覆盖a寄存器。有一种方法可以使用大写的寄存器名称(/ y A)来使vim附加到寄存器(请参阅: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的帮助可能有更好的起点)。

© www.soinside.com 2019 - 2024. All rights reserved.