使用我一直使用的当前颜色方案,在浏览搜索结果时很难找到光标的位置。突出显示的颜色和光标的颜色混合在一起使得很难找到光标。

当光标位于突出显示的单词上时如何设置不同的光标颜色?



#1 楼

我使用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。 />
更新:

我最近写了这个更高级的版本来回答另一个问题。它具有以下更改::


(可选)重复闪烁:Conway的原始版本仅闪烁一次:先打开然后再关闭,
允许您通过键入other来中断闪烁命令(例如再次按n跳至下一场比赛。)这使您可以设置更长的时间

UPDATE 2:

vim-searchhi插件提供了原始的请求的功能。

评论


效果很好。从现在开始,我将使用它。稍后我将尝试实现持久性。

–ma08
15年3月27日在18:02

前两行是做什么的?据我所知,没有使用分配的变量,如果我删除了这些行,它仍然可以工作。

–马丁·图尔诺伊(Martin Tournoij)
2015年5月3日23:02

@Carpetsmoker这些行(现在已删除)是很好的老式废话。如果您观看演讲,您将看到Conway经过几次迭代即可达到此解决方案。在较早的版本中使用了不必要的变量,但在本版本中没有使用。在真正开始学习vimscript之前,我将其复制到了.vimrc中,并且显然再也没有看过代码了,即使将其粘贴到答案中也是如此!发现得好。

–丰富
2015年5月5日,11:29

我最近用此代码段替换了vim-pulse(我认为这是)插件,它更好/更快了

– Craigp
2015年5月7日7:49

@Badger很高兴听到它。 :)

–丰富
15年6月26日在9:35

#2 楼

根据Rich的回答,这里有一些区别:


它会无限期地突出显示匹配电流,我发现闪烁着令人烦恼,并且在注册任何其他按键之前有0.1s的小延迟。 br />它包含了即使我开始搜索'?'或'#'时也能得到'n'的答案吗?


您可以使用清除突出显示<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>


#3 楼

您可以选择更好的颜色。只需将其放在您的vimrc上:

hi Cursor guifg=#121212 guibg=#afd700


评论


这总是一个选择,我只是想看看是否有可能根据上下文设置颜色。

–ma08
2015年3月27日13:55



我认为这没有用,但是您可以检测(在/或#上)搜索模式是否与光标下方的单词相同,并更改“光标”突出显示

–adelarsq
15年3月27日在14:10

#4 楼

我能想到的唯一方法是使用CursorMovedCursorMovedI 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在大多数终端中无法控制的内容。)
我找不到一种明显的方法来检查我所在的字符是否是当前搜索词和/或突出显示;唯一的方法是获取该行,并再次对@/进行正则表达式。根据您的设置,/match()之间的正则表达式解释可能会有一些细微的差异(请参阅:help match())。
我无法找到一种方法来检查我们当前是否正在突出显示某些内容,@/寄存器包含上次使用的搜索,无论我们要突出显示什么。因此,我要做的是重新映射/以首先设置g:searching变量以指示我们正在执行主动搜索,并使用<C-l>调用:nohlsearch来清除突出显示,并将g:searching设置为false以指示我们不在搜索...
每次光标移动时都会运行此命令,它可能不是很快,特别是对于大文件/行,缓慢的系统或复杂的正则表达式(虽然对我来说似乎还可以)。


#5 楼

为了使事情减至最少,但仍然对我来说完美,我从上面得到了启发:突出显示直到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>


现在,即使没有nhlsearch也会显示给我直到我移动光标为止的着陆位置。仅当一个字符匹配时,使用SpellRare使其更加生动,否则它是平滑的IncSearch

#6 楼

我尝试了此处列出的其他一些答案以及此处的解决方案,但发现它们分散了注意力并易于出现错误消息。 timakro编写了可解决该问题的插件,到目前为止对我来说效果很好。