Définir la couleur du curseur différemment sur un mot en surbrillance

19

Avec le schéma de couleurs actuel que j'utilise, il est difficile de trouver l'emplacement du curseur lors de la navigation dans les résultats de recherche. La couleur de surbrillance et la couleur du curseur se mélangent, ce qui rend difficile la recherche du curseur.

Comment définir une couleur de curseur différente lorsqu'elle se trouve sur un mot en surbrillance?

Capture d'écran du problème

ma08
la source

Réponses:

14

J'utilise cet extrait du discours fantastique de Damian Conway, More Instantly Better Vim (à 4m 59s). Cela fait clignoter brièvement la surbrillance entière lorsque vous sautez entre les résultats de la recherche.

" 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

Si vous souhaitez que le changement de surbrillance soit plus persistant, vous pouvez le modifier pour appeler matchdeleteà un autre moment (par exemple lorsque le curseur se déplace).

MISE À JOUR:

J'ai récemment écrit cette version plus avancée en réponse à une autre question. Il présente les modifications suivantes:

  1. (Facultatif) clignote à plusieurs reprises: la version originale de Conway ne clignote qu'une seule fois: allumée puis éteinte,
  2. Vous permet d'interrompre le clignotement en tapant d'autres commandes (comme appuyer à nnouveau pour passer à la correspondance suivante.) Cela vous permet de définir une durée plus longue

MISE À JOUR 2:

Le plugin vim-searchhi fournit la fonctionnalité initialement demandée.

Riches
la source
Fonctionne très bien. Je vais l'utiliser à partir de maintenant. J'essaierai d'implémenter le persistant un peu plus tard.
ma08
Que font les 2 premières lignes? Pour autant que je puisse voir, les variables attribuées ne sont pas utilisées, et si je supprime ces lignes, cela fonctionne toujours.
Martin Tournoij
@Carpetsmoker Ces lignes (maintenant supprimées) étaient une bonne cruauté à l'ancienne. Si vous regardez la conférence, vous verrez que Conway arrive à cette solution après quelques itérations. Les variables inutiles ont été utilisées dans les variantes précédentes, mais pas dans celle-ci. Je l'ai copié dans mon .vimrc avant de vraiment commencer à apprendre vimscript, et évidemment je n'ai plus jamais regardé le code, même en le collant dans ma réponse! Bien repéré.
Rich
J'ai récemment remplacé l'addon vim-pulse (je pense qu'il s'appelle) par cet extrait et il est bien meilleur / plus rapide
craigp
@Badger Heureux de l'entendre. :)
Rich
5

Basé sur la réponse de Rich ici avec quelques différences:

Vous pouvez effacer la surbrillance avec <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>
Martin Tournoij
la source
3

Vous pouvez choisir une meilleure couleur. Mettez juste ceci sur votre vimrc:

hi Cursor guifg=#121212 guibg=#afd700
adelarsq
la source
C'est toujours une option, je cherche juste à voir s'il est possible de régler la couleur en fonction du contexte.
ma08
Je ne pense pas que ce soit utile, mais vous pouvez détecter si le modèle de recherche (sur / ou #) est le même que le mot sous le curseur et changer la surbrillance du curseur
adelarsq
3

La seule façon dont je peux penser est d'utiliser les CursorMovedet CursorMovedIautocmds, ceux-ci sont invoqués chaque fois que le curseur est déplacé ...

Voici un code qui fait exactement cela:

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>/

Il y a quelques mises en garde :

  • Cela ne fonctionne que pour gVim, car la modification de la couleur du curseur n'est pas possible dans le terminal Vim (c'est quelque chose que vous configurez dans votre émulateur de terminal, et pas quelque chose que Vim peut contrôler dans la plupart des terminaux).

  • Je ne trouve pas de moyen évident de vérifier si le personnage sur lequel je me trouve fait partie du terme de recherche actuel et / ou est mis en surbrillance; la seule façon est d'obtenir la ligne, et d'exprimer cette expression (à nouveau) avec @/. Il peut y avoir quelques différences mineures sur l'interprétation des expressions rationnelles entre /et en match()fonction de vos paramètres (voir :help match()).

  • Je ne peux pas trouver un moyen de vérifier si nous mettons actuellement en évidence quelque chose, le @/registre contient la dernière recherche utilisée, indépendamment de ce que nous mettons en évidence. Donc, ce que j'ai fait, c'est remapper /pour définir d'abord la g:searchingvariable pour indiquer que nous faisons une recherche active, et avec <C-l>nous appelons :nohlsearchpour effacer la surbrillance, et défini g:searchingsur false pour indiquer que nous ne recherchons pas ...

  • Ceci est exécuté à chaque fois que le curseur se déplace , il peut ne pas être très rapide, en particulier pour les fichiers / lignes volumineux, les systèmes lents ou les regexps compliqués (cela semble cependant fonctionner correctement pour moi).

Martin Tournoij
la source
1

Pour garder les choses minimales, mais cela fonctionne toujours parfaitement pour moi, j'ai ceci, inspiré par le haut: surligner simplement jusqu'à 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>

Maintenant, nmême sans hlsearchme montre l'endroit où j'ai atterri jusqu'à ce que je déplace le curseur. Le SpellRareest utilisé pour le rendre plus ovbious lorsqu'un seul caractère correspond, sinon c'est le smoothIncSearch

perelo
la source
0

J'ai essayé certaines des autres réponses répertoriées ici et la solution ici, mais je les ai trouvées distrayantes et sujettes aux messages d'erreur. timakro a écrit un plugin qui résout le problème et fonctionne bien pour moi jusqu'à présent.

John
la source