Встановіть різний колір курсору, коли використовується слово, що виділяється


19

За допомогою поточної кольорової схеми, яку я використовував, важко знайти місце розташування курсору під час навігації по результатах пошуку. Колір виділення та колір курсору змішуються, що ускладнює пошук курсору.

Як встановити інший колір курсору, коли він знаходиться на виділеному слові?

Скріншот проблеми

Відповіді:


14

Я використовую цей фрагмент із фантастичної бесіди Даміана Конвей, « Миттєво кращий 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 просто блимає один раз: увімкнено, а потім вимкнено,
  2. Дозволяє перервати мерехтіння, ввівши інші команди (наприклад, nзнову натиснути, щоб перейти до наступного матчу.) Це дозволяє встановити довший час

ОНОВЛЕННЯ 2:

ВІМ-searchhi плагін забезпечує спочатку запитану функцію.


Чудово працює. Я буду використовувати це відтепер. Я спробую реалізувати стійкий десь пізніше.
ma08,

Що роблять перші 2 рядки? Наскільки я бачу, призначені змінні не використовуються, і якщо я видаляю ці рядки, вона все ще працює.
Мартін Турноїй

@Carpetsmoker Ці рядки (тепер видалено) були гарною старомодною суттю. Якщо ви подивитесь на розмову, то побачите, що Конвей приходить до цього рішення після кількох ітерацій. Непотрібні змінні використовувалися в попередніх варіантах, але не в цій. Я скопіював його у свій .vimrc ще до того, як я справді почав вивчати vimscript, і, очевидно, ніколи більше не переглядав код, навіть коли вставляв його у свою відповідь! Добре помічений.
Багатий

Нещодавно я замінив адмін на vim-pulse (я думаю, це називається) на цей фрагмент, і це набагато краще / швидше
craigp

@Badger Радий почути це. :)
Багатий

5

На основі відповіді Річа тут, з деякими відмінностями:

Ви можете очистити виділення за допомогою <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 написав плагін, який вирішує проблему і працює для мене добре.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.