这是一个后续行动,我的问题关于在Vim中使用多行正则表达式 。
一个快速的解释:我有文字标记块#tags
和一个空行分隔。 我想筛选出包含特定标签的所有块。 我用正则表达式在这里帮助,所以我构建了以下命令(谢谢!):
command -nargs=1 TagSearch g/^\(.\+\n\)\{-}.*#<args>.*/y a | vnew | put a | %s/^#.*<args>.*\n/&\r
因此,做一个:TagSearch tag
应:
- 搜索
#tag
, - 所有相应的文本块粘贴到一个新的垂直缓冲,
- 添加文本块之间的空行中新的缓冲区。
Q1:当我做单独的每一步,一切正常。 但该多命令仅粘贴第一匹配文本块到新的缓冲器。 为什么?
Q2:我如何才能让命令接受多个参数(如果我想要搜索的许多#tags
在时间)? 谢谢!
我们可以使用下面的实现。
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
我有一个很好的老摆弄这一点,并在这个过程中学习了很多! 貌似有这里发生了一些问题。
以下是我通过工作得到它的工作,但因为有这么多的方法用vim有可能莫名其妙地整洁的方式。
g命令的形式为克/图案/命令。 我认为是发生在你原来的形式,该| V新| 把| %S ...命令的一部分正在执行面向行与G命令,而不是一次作为TagSearch命令的一部分。 我改变了G指令在被“执行”,而不是解决了问题 - 我很想知道是否有指定什么管道适用于不使用执行的方式,我不能让它工作(括号不工作例如)。 这将是为什么你只得到了第一线。 这给了我们(固定在你的“%s”的命令一个错字):
command! -nargs=1 TagSearch execute 'g/^\(.\+\n\)\{-}.*#<args>.*/y a' | vnew | put a | %s/^.*#<args>.*\n/&\r
这似乎虽然扭转问题,我们现在只得到在新的缓冲区中的最后一行。 另一个问题与G命令,就是当你/你,它会覆盖每次寄存器。 有一个办法让VIM将追加到寄存器中,而不使用大写的寄存器名(/ Y A)(见:帮助quotea)。 这样做,这样我们需要的寄存器初始化为空白的第一,使用让。 这给了我们这样的:
command! -nargs=1 TagSearch let @a='' | execute 'g/^\(.\+\n\)\{-}.*#<args>.*/y A' | vnew | put a | %s/^.*#<args>.*\n/&\r
最后得到它与多个标签execture,我只是拨弄着<args>
位(呼叫TagSearch标签1 TAG2,ARGS会从字面上是字符串“TAG1标签2”)来获得它适合在下面的正则表达式:
command! -nargs=* TagSearch let @a='' | execute 'g/^\(.\+\n\)\{-}.*#\(' . substitute('<args>', ' ', '\\|', 'g') . '\).*/y A' | vnew | put a | execute '%s/^.*#\(' . substitute('<args>', ' ', '\\|', 'g') . '\).*\n/&\r'
如果你添加更多的功能到这一点,你可能想尝试玩弄一个小vim脚本功能什么的来代替,否则可能会相当困难,保持! 你能抓住你的文本块成漂亮的名单,并可能对其进行处理多一点轻松,而不是做的一切,如果你是真正打字。 看一看:帮助功能的东西可用(虽然有可能在帮助Vimscript中的其他地方一个更好的起点)。