VIM增量搜索,如何复制光标下的匹配字符串?

VIM增量搜索,如何复制光标下的匹配字符串?,vim,Vim,在VIM中,可以搜索指定的字符串。然后您可以按n或n导航下一个或上一个匹配。按n或n时,光标将移动到匹配的文本。我的问题是,如何快速复制光标下的匹配文本 编辑: 我需要的是光标下的当前匹配项,而不是文档中的所有匹配项。按y键,光标下的文本将复制到未修改的默认寄存器,然后您可以按p键粘贴。是否要执行以下操作 y//e 概述: 基本思路是搜索或按n或n后,光标将位于匹配文本的开头。然后你猛拉到最后一次搜索的末尾 解释 y将通过以下动作从当前位置猛拉 /使用最后一个搜索模式进行搜索 /ee标志将

在VIM中,可以搜索指定的字符串。然后您可以按n或n导航下一个或上一个匹配。按n或n时,光标将移动到匹配的文本。我的问题是,如何快速复制光标下的匹配文本


编辑:


我需要的是光标下的当前匹配项,而不是文档中的所有匹配项。

按y键,光标下的文本将复制到未修改的默认寄存器,然后您可以按p键粘贴。

是否要执行以下操作

y//e
概述:

基本思路是搜索或按
n
n
后,光标将位于匹配文本的开头。然后你猛拉到最后一次搜索的末尾

解释

  • y
    将通过以下动作从当前位置猛拉
  • /
    使用最后一个搜索模式进行搜索
  • /e
    e标志将光标定位在匹配文本的末尾
作为警告,这将改变当前的搜索模式,因为它添加了
/e
标志。因此,遵循
n
和/或
n
将光标移动到匹配的末尾


这与下面的内容非常相似

我想这应该可以:

command! -register CopyExactMatchUnderCursor call s:CopyExactMatchUnderCursor('<reg>')

function! s:CopyExactMatchUnderCursor(reg)
    let cpos = getpos('.')
    let line = cpos[1]
    let idx = cpos[2] - 1
    let txt = getline(line)

    let mend = matchend(txt, @/, idx)

    if mend > idx
        let sel = strpart(txt, idx, mend - idx)

        let reg = empty(a:reg) ? '"' : a:reg
        execute 'let @' . reg . ' = sel . "\n"'
    end
endfunction
命令-注册CopyExactMatchUnderCorsor调用s:CopyExactMatchUnderCorsor(“”)
功能!s:CopyExactMatchUndersersor(注册)
让cpos=getpos('.'))
let line=cpos[1]
设idx=cpos[2]-1
让txt=getline(line)
让mend=matchend(txt,@/,idx)
如果mend>idx
设sel=strpart(txt,idx,mend-idx)
让reg=空(a:reg)?'“':a:reg
执行'let@'.reg.'=sel.\n''
结束
端功能
它首先用
getpos
获取光标位置,然后搜索匹配的结尾(从光标使用
matchend
的列开始),然后返回提供的寄存器中的子字符串-默认情况下使用


所有必要的方法基本上都在@eckes answer中。

可以编写一个函数来提取最后一个搜索模式的匹配项 并创建一个映射来调用它

nnoremap <silent> <leader>y :call setreg('"', MatchAround(@/), 'c')<cr>
function! MatchAround(pat)
    let [sl, sc] = searchpos(a:pat, 'bcnW')
    let [el, ec] = searchpos(a:pat, 'cenW')
    let t = map(getline(sl ? sl : -1, el), 'v:val."\n"')
    if len(t) > 0
        let t[0] = t[0][sc-1:]
        let ec -= len(t) == 1 ? sc-1 : 0
        let t[-1] = t[-1][:matchend(t[-1], '.', ec-1)-1]
    end
    return join(t, '')
endfunction
要使用这些映射复制当前匹配,请使用
yi/
。至于其他文本 对象,例如,也可以使用
vi/
直观地选择它,
或者使用
di/

删除它上面的函数通常不能解决问题:如果当前匹配跨越多行,它将不会删除任何内容。请注意,上面的函数可以正确处理一个字符或多行匹配。我建议在映射中使用
v:register
:让@“.v:register.'=MatchAroundCursor(@/)”谢谢ib。我已将您的函数粘贴到我的.vimrc中。怎么称呼他们?我是VIM的新手。谢谢。上面代码片段的第一行是映射。如果您还将该行复制到了
.vimrc
文件中,则每当光标位于搜索模式匹配上时,按前导键(默认情况下为反斜杠),后跟
y
,匹配将被拉长。@Benoit:谢谢您的好主意!顺便说一句,最好使用
setreg()
来更改寄存器的内容(因为字符/行/块模式问题)。除了更改标志的恼人缺点外,如果当前匹配只有一个字符长,这种方法无法按预期工作!在Vim提示中,FAQ涵盖了这个主题。人们可能还对问题“”感兴趣。
vnoremap <silent> i/ :<c-u>call SelectMatch()<cr>
onoremap <silent> i/ :call SelectMatch()<cr>
function! SelectMatch()
    if search(@/, 'bcW')
        norm! v
        call search(@/, 'ceW')
    else
        norm! gv
    endif
endfunction