在突出显示的单词上设置光标颜色不同


19

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

在光标突出显示的单词上如何设置不同的光标颜色?

问题的屏幕截图

Answers:


14

我使用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在其他时间调用(例如,当光标移动时)。

更新:

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

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

更新2:

VIM-searchhi插件提供原请求的功能。


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

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

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

我最近更换了VIM脉冲(我认为这是所谓的),在这个片段中的插件,它是更好/更快
craigp

@Badger很高兴听到它。:)
Rich Rich 2015年

5

根据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>

3

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

hi Cursor guifg=#121212 guibg=#afd700

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

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

3

我能想到的唯一方法是使用CursorMovedCursorMovedIautocmds,它们在每次移动光标时都会被调用...

这是一些准确地做到这一点的代码:

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以指示我们不在搜索...

  • 每次光标移动都会运行此命令,它可能不是很快,特别是对于大文件/行,缓慢的系统或复杂的正则表达式(尽管对我来说似乎可以正常工作)。


1

为了使事情减至最少,但仍然对我来说效果很好,我受到了以上启发:突出显示,直到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


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.