Answers:
我使用Damian Conway精彩演讲中的摘录,即更即时更好的Vim(4m 59s)。当您在搜索结果之间跳转时,它会使整个突出显示短暂闪烁。
" Damian Conway's Die Blinkënmatchen: highlight matches
nnoremap <silent> n n:call HLNext(0.1)<cr>
nnoremap <silent> N N:call HLNext(0.1)<cr>
function! HLNext (blinktime)
let target_pat = '\c\%#'.@/
let ring = matchadd('ErrorMsg', target_pat, 101)
redraw
exec 'sleep ' . float2nr(a:blinktime * 1000) . 'm'
call matchdelete(ring)
redraw
endfunction
如果您希望突出显示的更改更加持久,则可以对其进行调整以matchdelete
在其他时间调用(例如,当光标移动时)。
我最近写了这个更高级的版本来回答另一个问题。它具有以下更改::
n
再次按下以跳到下一场比赛。)这可以让您设置更长的时间该VIM-searchhi插件提供原请求的功能。
根据Rich的回答,这里有一些区别:
您可以使用清除突出显示的内容<C-l>
。
fun! SearchHighlight()
silent! call matchdelete(b:ring)
let b:ring = matchadd('ErrorMsg', '\c\%#' . @/, 101)
endfun
fun! SearchNext()
try
execute 'normal! ' . 'Nn'[v:searchforward]
catch /E385:/
echohl ErrorMsg | echo "E385: search hit BOTTOM without match for: " . @/ | echohl None
endtry
call SearchHighlight()
endfun
fun! SearchPrev()
try
execute 'normal! ' . 'nN'[v:searchforward]
catch /E384:/
echohl ErrorMsg | echo "E384: search hit TOP without match for: " . @/ | echohl None
endtry
call SearchHighlight()
endfun
" Highlight entry
nnoremap <silent> n :call SearchNext()<CR>
nnoremap <silent> N :call SearchPrev()<CR>
" Use <C-L> to clear some highlighting
nnoremap <silent> <C-L> :silent! call matchdelete(b:ring)<CR>:nohlsearch<CR>:set nolist nospell<CR><C-L>
您可以选择更好的颜色。只需将其放在您的vimrc上:
hi Cursor guifg=#121212 guibg=#afd700
我能想到的唯一方法是使用CursorMoved
和CursorMovedI
autocmds,它们在每次移动光标时都会被调用...
这是一些准确地做到这一点的代码:
fun! CursorColour()
if !g:searching | return | endif
let l:prev_end = 0
" Loop until we've found all matches of the current search pattern
while 1
let l:start = match(getline('.'), @/, l:prev_end)
" No more matches: stop looping
if l:start == -1 | break | endif
let l:cursor = col('.')
" Check if the cursor is inside the string
if l:cursor > l:start && l:cursor <= l:start + strlen(@/)
hi Cursor guifg=#121212 guibg=#afd700
return
endif
" Set start location for next loop iteration
let l:prev_end = l:start + strlen(@/)
endwhile
" We return if we're on a highlighted string, if we're here we didn't
" match anything
call ResetCursorColour()
endfun
fun! ResetCursorColour()
hi Cursor guifg=#ffffff guibg=#000000
endfun
autocmd CursorMoved,CursorMovedI * call CursorColour()
let g:searching=0
nnoremap <silent> <C-L> :nohlsearch<CR>:let g:searching=0<CR>:call ResetCursorColour()<CR><C-L>
nnoremap / :let g:searching=1<CR>/
有一些警告:
这仅适用于gVim,因为无法在终端Vim中更改光标颜色(这是您在终端仿真器中配置的,并非Vim在大多数终端中都可以控制)。
我找不到一种明显的方法来检查我所在的字符是否是当前搜索词的一部分和/或是否突出显示了;唯一的方法是获取该行,并再次进行regexp @/
。有可能是对正则表达式之间演绎一些细微的差别/
,并match()
根据您的设置(请参阅:help match()
)。
我无法找到一种方法来检查我们当前是否实际上在突出显示某些@/
内容,无论我们在突出显示什么内容,寄存器都包含上一次使用的搜索。因此,我要做的是重新映射/
以首先设置g:searching
变量以指示我们正在进行主动搜索,并通过<C-l>
调用:nohlsearch
以清除突出显示,并设置g:searching
为false以指示我们不在搜索...
每次光标移动都会运行此命令,它可能不是很快,特别是对于大文件/行,缓慢的系统或复杂的正则表达式(尽管对我来说似乎可以正常工作)。
为了使事情减至最少,但仍然对我来说效果很好,我受到了以上启发:突出显示,直到CursorMoved
:
function! HLNext()
let l:higroup = matchend(getline('.'), '\c'.@/, col('.')-1) == col('.')
\ ? 'SpellRare' : 'IncSearch'
let b:cur_match = matchadd(l:higroup, '\c\%#'.@/, 101)
redraw
augroup HLNext
autocmd CursorMoved <buffer>
\ execute 'silent! call matchdelete('.b:cur_match.')'
\ | redraw
\ | autocmd! HLNext
augroup END
endfunction
nnoremap <silent> * *:call HLNext()<CR>
nnoremap <silent> # #:call HLNext()<CR>
nnoremap <silent> n n:call HLNext()<cr>
nnoremap <silent> N N:call HLNext()<cr>
现在,n
即使没有hlsearch
向我显示,直到我移动光标之前,我着陆的地方也是如此。本SpellRare
是用来使其更当只有一个字符匹配ovbious,否则就顺利IncSearch