Stellen Sie die Cursorfarbe bei einem hervorgehobenen Wort anders ein

19

Mit dem aktuellen Farbschema, das ich verwendet habe, ist es schwierig zu finden, wo sich der Cursor befindet, wenn ich durch die Suchergebnisse navigiere. Die Hervorhebungsfarbe und die Cursorfarbe verschmelzen, sodass der Cursor nur schwer zu finden ist.

Wie stelle ich die Cursorfarbe anders ein, wenn es sich um ein hervorgehobenes Wort handelt?

Screenshot des Problems

ma08
quelle

Antworten:

14

Ich benutze diesen Ausschnitt aus Damian Conways fantastischem Vortrag " More Instantly Better Vim" (um 4 Uhr 59). Dadurch blinkt die gesamte Markierung kurz, wenn Sie zwischen den Suchergebnissen wechseln.

" 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

Wenn Sie möchten, dass die Änderung der Hervorhebung länger anhält, können Sie dies ändern, um sie matchdeletezu einem anderen Zeitpunkt aufzurufen (z. B. wenn sich der Cursor bewegt).

AKTUALISIEREN:

Ich habe kürzlich diese erweiterte Version als Antwort auf eine andere Frage geschrieben. Es hat die folgenden Änderungen:

  1. (Optional) blinkt wiederholt: Die Originalversion von Conway blinkt nur einmal: ein und dann aus,
  2. Ermöglicht das Unterbrechen des Blinkens durch Eingeben anderer Befehle (z. B. erneutes Drücken n, um zum nächsten Treffer zu springen). Auf diese Weise können Sie eine längere Zeit einstellen

UPDATE 2:

Das vim-searchhi- Plugin bietet die ursprünglich angeforderte Funktion.

Reich
quelle
Funktioniert super. Ich werde dies von jetzt an verwenden. Ich werde später versuchen, die persistente zu implementieren.
ma08
Was machen die ersten 2 Zeilen? Soweit ich sehen kann, werden die zugewiesenen Variablen nicht verwendet, und wenn ich diese Zeilen entferne, funktioniert es immer noch.
Martin Tournoij
@Carpetsmoker Diese Zeilen (jetzt gelöscht) waren gute altmodische Cruft. Wenn Sie sich den Vortrag ansehen, werden Sie feststellen, dass Conway nach einigen Iterationen zu dieser Lösung gelangt. Die unnötigen Variablen wurden in den früheren Variationen verwendet, jedoch nicht in dieser. Ich habe es in meine .vimrc kopiert, bevor ich wirklich anfing, Vimscript zu lernen, und habe mir den Code offensichtlich nie wieder angesehen, selbst wenn ich ihn in meine Antwort eingefügt habe! Gut beobachtet.
Rich
Ich habe kürzlich das vim-pulse-Addon (ich glaube, es heißt) durch dieses Snippet ersetzt und es ist viel besser / schneller
craigp
@Badger Freut mich zu hören. :)
Rich
5

Basierend auf Richs Antwort hier mit einigen Unterschieden:

Sie können die Hervorhebung mit löschen <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
quelle
3

Sie können eine bessere Farbe wählen. Setzen Sie dies einfach auf Ihr vimrc:

hi Cursor guifg=#121212 guibg=#afd700
adelarsq
quelle
Das ist immer eine Option, ich suche nur, ob es möglich ist, die Farbe dem Kontext entsprechend einzustellen.
ma08
Ich halte das nicht für nützlich, aber Sie können feststellen, ob das Suchmuster (auf / oder #) mit dem Wort unter dem Cursor
übereinstimmt,
3

Die einzige Möglichkeit, die ich mir vorstellen kann, ist die Verwendung von CursorMovedund CursorMovedIautocmds, die jedes Mal aufgerufen werden, wenn der Cursor bewegt wird ...

Hier ist ein Code, der genau das macht:

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

Es gibt einige Einschränkungen :

  • Dies funktioniert nur für gVim, da das Ändern der Cursorfarbe in Terminal Vim nicht möglich ist (dies ist etwas, das Sie in Ihrem Terminal-Emulator konfigurieren, und nicht etwas, das Vim in den meisten Terminals steuern kann).

  • Ich kann keine offensichtliche Möglichkeit finden, um zu überprüfen, ob der Charakter, auf dem ich mich befinde, Teil des aktuellen Suchbegriffs ist und / oder hervorgehoben wird. der einzige Weg ist, die Zeile zu bekommen und diese (wieder) mit regexp @/. Möglicherweise gibt es einige kleinere Unterschiede auf regexp Interpretation zwischen sein /und match()je nach Einstellung (siehe :help match()).

  • Ich kann nicht herausfinden, ob wir gerade etwas hervorheben. Das @/Register enthält die zuletzt verwendete Suche, unabhängig davon, was wir hervorheben. Also, was ich getan habe, ist eine Neuzuordnung, /um zuerst die g:searchingVariable festzulegen , um anzuzeigen, dass wir eine aktive Suche durchführen, und mit <C-l>rufen wir :nohlsearchauf, um die Hervorhebung zu löschen, und g:searchingauf false, um anzuzeigen, dass wir nicht suchen ...

  • Dies wird jedes Mal ausgeführt, wenn sich der Cursor bewegt. Dies ist möglicherweise nicht sehr schnell, insbesondere bei großen Dateien / Zeilen, langsamen Systemen oder komplizierten regulären Ausdrücken (es scheint jedoch für mich in Ordnung zu sein).

Martin Tournoij
quelle
1

Um die Dinge so klein wie möglich zu halten und trotzdem perfekt für mich zu funktionieren, habe ich Folgendes von oben inspiriert: Einfaches Highlight bis 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>

Jetzt zeigt mir nauch ohne hlsearch, wo ich gelandet bin, bis ich den Cursor bewege. Das SpellRarewird verwendet, um es eifriger zu machen, wenn nur ein einziges Zeichen übereinstimmt, ansonsten ist es das GlatteIncSearch

perelo
quelle
0

Ich habe einige der anderen hier aufgeführten Antworten und die Lösung hier ausprobiert , fand sie jedoch ablenkend und anfällig für Fehlermeldungen. timakro hat ein Plugin geschrieben , das das Problem löst und für mich bisher gut funktioniert.

John
quelle