ハイライトされた単語上でカーソルの色を変える


19

現在使用しているカラースキームでは、検索結果をナビゲートするときにカーソルの位置を見つけるのは困難です。ハイライトの色とカーソルの色が混ざり合って、カーソルを見つけにくくなっています。

強調表示された単語上にあるときにカーソルの色をどのように設定しますか?

問題のスクリーンショット

回答:


14

このスニペットは、Damian Conwayの素晴らしい講演「More Instantly Better Vim」(4分59秒)を使用しています。検索結果間をジャンプすると、ハイライト全体が短時間点滅します。

" 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の元のバージョンは1回だけ点滅します:オン、オフ、
  2. 他のコマンドを入力して点滅を中断できます(n次の一致にジャンプするためにもう一度押すなど)。これにより、より長い時間を設定できます。

更新2:

VIM-searchhiプラグインは、もともと要求された機能を提供します。


よく働く。これからこれを使用します。永続的なものを後で実装しようとします。
-ma08

最初の2行は何をしますか?私が見る限り、割り当てられた変数は使用されず、それらの行を削除しても機能します。
マーティントゥルノイ

@Carpetsmokerこれらの行(現在は削除されています)は、古風なクラフでした。トークを見ると、Conwayが数回の反復の後にこのソリューションに到達していることがわかります。不要な変数は以前のバリエーションで使用されていましたが、このバリエーションでは使用されていませんでした。実際にvimscriptの学習を開始する前に、それを.vimrcにコピーしました。答えに貼り付けても、明らかにコードを再び見たことはありません!よく見つけた。
リッチ

私は最近、vim-pulse(と呼ばれると思います)アドオンをこのスニペットに置き換えました。これはずっと良い/速いです
-craigp

@Badgerうれしい。:)
リッチ

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

これは常にオプションです。コンテキストに応じて色を設定できるかどうかを確認しています。
ma08

私はそれは有用ではないと思いますが、検索パターン(オン/または#)がカーソルの下の単語と同じかどうかを検出し、カーソルの強調表示を変更できます
adelarsq

3

私が考えることができる唯一の方法は、CursorMovedおよびCursorMovedIautocmds を使用することです。これらはカーソルが移動するたびに呼び出されます...

これを正確に行うコードを次に示します。

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に設定しました...

  • これは、カーソルが移動するたびに実行され、特に大きなファイル/行、遅いシステム、複雑な正規表現ではあまり高速ではないかもしれません(私にとってはうまくいくようです)。


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はこの問題を解決するプラグインを作成し、これまでのところうまく機能しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.