Regex VIM-当前缓冲区中视觉选择时VIMGREP的热键

Regex VIM-当前缓冲区中视觉选择时VIMGREP的热键,regex,vim,vi,vimgrep,Regex,Vim,Vi,Vimgrep,如何设置热键(例如:CTRL+g)以对当前缓冲区中的当前视觉选择执行VIMGREP操作?我的目的是在“快速修复”窗口中显示所有匹配搜索结果的行号列表 现在,如果我想获得正则表达式搜索的结果列表,我可以执行如下命令模式查询: :vimgrep /foo/ % 但是,这有两个问题: 我不想输入整个查询。我总是可以做一个视觉选择,然后使用CTRL+r、CTRL+w将当前的视觉选择粘贴到命令缓冲区中,但是我想要比这更简单的东西 上述方法要求当前缓冲区已保存到文件中。我希望能够处理粘贴到VIM中的临时缓

如何设置热键(例如:CTRL+g)以对当前缓冲区中的当前视觉选择执行
VIMGREP
操作?我的目的是在“快速修复”窗口中显示所有匹配搜索结果的行号列表

现在,如果我想获得正则表达式搜索的结果列表,我可以执行如下命令模式查询:

:vimgrep /foo/ %
但是,这有两个问题:

  • 我不想输入整个查询。我总是可以做一个视觉选择,然后使用CTRL+r、CTRL+w将当前的视觉选择粘贴到命令缓冲区中,但是我想要比这更简单的东西
  • 上述方法要求当前缓冲区已保存到文件中。我希望能够处理粘贴到VIM中的临时缓冲区,而不是每次都要保存文件缓冲区

  • 谢谢。

    要通过热键CTRL+g搜索文件*.c中的可视选定文本,请执行以下操作:

    (对不起,我现在没有时间在这里显示脚本解决方案,也许我以后会添加一个。也许其他人有更好的解决方案,或者可以提供脚本?)

    至2: 此命令将启用当前缓冲区中的行号:

    :set number
    
    低级解决方案 尝试
    [I
    :ilist
    命令:

    [I”列出光标下出现的每个单词
    “在当前缓冲区中(包括)
    :ilist/foo“列出当前缓冲区中每次出现的foo
    “(包括)
    
    后接行号,然后按
    跳转到该行

    您可以通过简单的映射在视觉选择上使用它们:

    xnoremap“vy:ilist/v:
    
    不过,您可能需要在插入时对寄存器进行消毒

    请参见
    :帮助:ilist

    另一个更低级别的解决方案 既然我们已经做到了,让我们更深入地挖掘,发现令人惊讶的简单和优雅:

    :g/foo/#
    
    您可以使用与上面的
    :ilist
    相同的方法:

    xnoremap“vy:g/v/#
    
    局限性 显然,上述解决方案不使用quickfix窗口,但它们允许您:

    • 将其结果作为列表查看
    • 使用行号实际到达您想要的位置
    但它们也有局限性:

    • 列表未缓存,因此如果要获取其他引用,必须再次执行搜索
    • 该列表不像quickfix列表那样是暂时的,因此不能使用导航命令(如
      :cnext
      :clast
      )在结果中移动
    更高层次的解决方案 如果这些限制是一个障碍,下面的函数根据justinmk在中的回答改编,为您提供了一个几乎完整的解决方案:

    • 在正常模式下按
      [I
      在整个缓冲区中搜索光标下的单词
    • 在正常模式下按
      ]I
      可搜索光标下当前行后的单词
    • 在视觉模式下按
      [I
      在整个缓冲区中搜索所选文本
    • 在视觉模式下按
      ]I
      可在当前行后搜索所选文本
    当缓冲区与文件关联时,下面的函数使用快速修复列表/窗口,并返回到
    [I
    ]I
    的常规行为。否则,它可能会被修改为用作
    :Ilist
    命令的一部分

    “在快速修复窗口中显示]I和[I结果”。
    请参阅:帮助包括搜索。
    函数!Ilist_qf(选择,在光标处开始)
    “有一个文件与此缓冲区关联
    如果len(展开(%)>0
    “我们正在处理视觉上选定的文本
    如果a:选择
    “我们从视觉选择构建了一个干净的搜索模式
    让old_reg=@v
    正常!gv“vy
    让search\u pattern=substitute(转义(@v,'\/.$^~[]),'\\n','\\n',g')
    让@v=old\u reg
    “我们重定向命令的输出以供以后使用
    redir=>输出
    静默!执行(a:start_at_cursor?'+,$:'')。'ilist/'。搜索模式
    重拨端
    “我们正在处理光标下的单词
    其他的
    “我们重定向命令的输出以供以后使用
    redir=>输出
    静默!执行“正常!”。(a:在光标处启动“?”]:“[”)“I”
    重拨端
    恩迪夫
    让行=拆分(输出“\n”)
    “安全总比后悔好
    如果第[0]行=检测到“^Error”
    echomsg“找不到”。(a:选择?搜索模式:展开(“”)。”
    返回
    恩迪夫
    “我们检索文件名
    让[文件名,行信息]=[行[0],行[1:-1]]
    “我们将:ilist输出转换为快速修复词典
    让qf\u条目=映射(行\u信息,“{
    \“文件名”:文件名,
    \“lnum”:拆分(v:val)[1],
    \“text”:getline(拆分(v:val)[1])
    \ }")
    调用设置QFLIST(qf_条目)
    “如果有什么要显示,我们最终会打开quickfix窗口
    cwindow
    “没有与此缓冲区关联的文件
    其他的
    “我们正在处理视觉上选定的文本
    如果a:选择
    “我们从视觉选择构建了一个干净的搜索模式
    让old_reg=@v
    正常!gv“vy
    让search\u pattern=substitute(转义(@v,'\/.$^~[]),'\\n','\\n',g')
    让@v=old\u reg
    “我们尝试执行搜索
    尝试
    执行(a:start_at_cursor?'+,$:'')。“ilist/”.搜索_模式。“:”
    抓住
    echomsg'找不到“'。搜索模式。“”
    
    let s:tmpfile = tempname()
    
    :set number
    
    :g/mypattern/caddexpr expand("%") . ":" . line(".") .  ":" . getline(".")
    
    command! -nargs=1 -bar Cgrep
          \ let s:errorformat = &errorformat |
          \ try |
          \   let &errorformat='%f:%l:%m' |
          \   cexpr [] |
          \   execute 'g'.<q-args>.'caddexpr expand("%").":".line(".").":".getline(".")' |
          \   cc |
          \ finally |
          \   let &errorformat = s:errorformat |
          \ endtry
    
    xnoremap g/ y:<c-u>Cgrep/<c-r>"/<cr>
    
    xnoremap g/ :<c-u>let @/=@"<cr>gvy:let [@/,@"]=[@",@/]<cr>Cgrep/\V<cr>=substitute(escape(@/,'/\'),'\n','\\n','g')<cr>/<cr>
    
    :h :caddexpr
    :h :cexpr
    :h :g
    :h 'efm
    :h registers
    :h /\V