Imposta il colore del cursore in modo diverso quando su una parola evidenziata


19

Con l'attuale colore che sto usando, è difficile trovare la posizione del cursore durante la navigazione tra i risultati della ricerca. Il colore di evidenziazione e il colore del cursore si fondono nel rendere difficile la ricerca del cursore.

Come si imposta il colore del cursore in modo diverso quando si trova su una parola evidenziata?

Schermata del problema

Risposte:


14

Uso questo frammento del fantastico discorso di Damian Conway, More Instantly Better Vim (a 4m 59s). Fa lampeggiare brevemente l'intero momento saliente quando salti tra i risultati della ricerca.

" 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

Se si desidera che il cambiamento nell'evidenziazione sia più persistente, è possibile modificarlo per richiamarlo matchdeletein un altro momento (ad esempio quando il cursore si sposta).

AGGIORNARE:

Di recente ho scritto questa versione più avanzata in risposta a un'altra domanda. Ha le seguenti modifiche:

  1. (Opzionalmente) lampeggia ripetutamente: la versione originale di Conway lampeggia solo una volta: acceso e poi spento,
  2. Ti permette di interrompere il lampeggiamento digitando altri comandi (come premere di nnuovo per passare alla partita successiva). Ciò ti consente di impostare un tempo più lungo

AGGIORNAMENTO 2:

Il plug -in vim-searchhi fornisce la funzione originariamente richiesta.


Funziona alla grande. Lo userò da ora. Cercherò di implementare quello persistente qualche tempo dopo.
ma08

Cosa fanno le prime 2 righe? Per quanto posso vedere, le variabili assegnate non vengono utilizzate e, se rimuovo quelle righe, funziona ancora.
Martin Tournoij,

@Carpetsmoker Quelle linee (ora cancellate) erano buone cruft vecchio stile. Se guardi il discorso, vedrai che Conway arriva a questa soluzione dopo alcune iterazioni. Le variabili non necessarie sono state utilizzate nelle varianti precedenti, ma non in questa. L'ho copiato nel mio .vimrc prima di iniziare davvero ad imparare vimscript, e ovviamente non ho mai più guardato il codice, anche quando lo ho incollato nella mia risposta! Ben individuato.
Ricco

Di recente ho sostituito l'addon vim-pulse (penso che si chiami) con questo frammento ed è molto meglio / più veloce
craigp

@Badger Lieto di sentirlo. :)
Rich

5

Basato sulla risposta di Rich qui con alcune differenze:

È possibile cancellare l'evidenziazione con <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

Puoi scegliere un colore migliore. Metti questo sul tuo vimrc:

hi Cursor guifg=#121212 guibg=#afd700

Questa è sempre un'opzione, sto solo cercando di vedere se è possibile impostare il colore in base al contesto.
ma08,

Non penso che sia utile, ma puoi rilevare se il modello di ricerca (on / o #) è lo stesso della parola sotto il cursore e modificare l'evidenziazione del cursore
adelarsq

3

L'unico modo in cui riesco a pensare è usando i tasti CursorMovede CursorMovedIautocmds, questi vengono invocati ogni volta che si sposta il cursore ...

Ecco un po 'di codice che fa esattamente questo:

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

Ci sono alcuni avvertimenti :

  • Questo funziona solo per gVim, poiché non è possibile modificare il colore del cursore nel terminale Vim (questo è qualcosa che si configura nell'emulatore di terminale e non qualcosa che Vim può controllare nella maggior parte dei terminali).

  • Non riesco a trovare un modo ovvio per verificare se il personaggio in cui mi trovo fa parte del termine di ricerca corrente e / o viene evidenziato; l'unico modo è ottenere la linea e ripeterla (di nuovo) con @/. Potrebbero esserci alcune piccole differenze nell'interpretazione di regexp tra /e in match()base alle tue impostazioni (vedi :help match()).

  • Non riesco a trovare un modo per verificare se attualmente stiamo evidenziando qualcosa, il @/registro contiene l'ultima ricerca utilizzata, indipendentemente da ciò che stiamo evidenziando. Quindi quello che ho fatto è stato rimappare /per prima cosa impostare la g:searchingvariabile per indicare che stiamo facendo una ricerca attiva, e con <C-l>noi chiamiamo :nohlsearchper cancellare l'evidenziazione, e impostare g:searchingsu falso per indicare che non stiamo cercando ...

  • Questo viene eseguito ogni volta che il cursore si sposta , potrebbe non essere molto veloce soprattutto per file / linee di grandi dimensioni, sistemi lenti o regexps complicati (sembra funzionare bene per me però).


1

Per mantenere le cose minime, ma funziona ancora perfettamente per me, ho questo, ispirato dall'alto: chiaro highlight fino a 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>

Ora, nanche senza hlsearchmi mostra dove sono atterrato fino a quando non sposto il cursore. La SpellRaresi usa per renderla più ovbious quando solo un singolo personaggio partite, altrimenti è il regolareIncSearch


0

Ho provato alcune delle altre risposte elencate qui e la soluzione qui, ma le ho trovate distraenti e soggette a messaggi di errore. timakro ha scritto un plugin che risolve il problema e finora funziona bene per me.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.