Đặt màu con trỏ khác nhau khi trên một từ được tô sáng


19

Với colourscheme hiện tại tôi đang sử dụng, thật khó để tìm thấy vị trí của con trỏ khi điều hướng qua các kết quả tìm kiếm. Màu sắc nổi bật và màu con trỏ đang hòa trộn vào nhau khiến bạn khó tìm thấy con trỏ.

Làm cách nào để đặt màu con trỏ khác nhau khi nó ở trên một từ được tô sáng?

Ảnh chụp màn hình của vấn đề

Câu trả lời:


14

Tôi sử dụng đoạn trích này từ bài nói chuyện tuyệt vời của Damian Conway, Vim tốt hơn ngay lập tức (ở 4m 59s). Nó khiến toàn bộ phần tô sáng nhấp nháy nhanh khi bạn nhảy giữa các kết quả tìm kiếm.

" 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

Nếu bạn muốn thay đổi trong tô sáng trở nên bền bỉ hơn, bạn có thể điều chỉnh điều này để gọi matchdeletevào lúc khác (ví dụ: khi con trỏ di chuyển).

CẬP NHẬT:

Gần đây tôi đã viết phiên bản nâng cao hơn này để trả lời cho một câu hỏi khác. Nó có những thay đổi sau ::

  1. (Tùy chọn) nhấp nháy liên tục: Phiên bản gốc của Conway chỉ nhấp nháy một lần: bật và sau đó tắt,
  2. Cho phép bạn làm gián đoạn nhấp nháy bằng cách nhập các lệnh khác (chẳng hạn như nhấn nlần nữa để chuyển sang trận đấu tiếp theo.) Điều này cho phép bạn đặt thời gian lâu hơn

CẬP NHẬT 2:

Các vim-searchhi plugin cung cấp các tính năng yêu cầu ban đầu.


Công trình tuyệt vời. Tôi sẽ sử dụng điều này từ bây giờ. Tôi sẽ cố gắng thực hiện cái liên tục sau đó.
ma08

2 dòng đầu tiên làm gì? Theo như tôi có thể thấy, các biến được gán không được sử dụng và nếu tôi loại bỏ các dòng đó, nó vẫn hoạt động.
Martin Tournoij

@Carpetsmoker Những dòng đó (hiện đã bị xóa) là loại cruft lỗi thời. Nếu bạn xem cuộc nói chuyện, bạn sẽ thấy Conway đến giải pháp này sau một vài lần lặp. Các biến không cần thiết đã được sử dụng trong các biến thể trước đó, nhưng không phải trong biến thể này. Tôi đã sao chép nó vào .vimrc của mình trước khi tôi thực sự bắt đầu học vimscript, và rõ ràng không bao giờ nhìn lại mã, ngay cả khi dán nó vào câu trả lời của tôi! Cũng phát hiện ra.
Giàu

Gần đây tôi đã thay thế addon xung vim (tôi nghĩ nó được gọi là) với đoạn trích này và nó tốt hơn / nhanh hơn nhiều
craigp

@Badger Vui mừng khi nghe nó. :)
Giàu

5

Dựa trên câu trả lời của Rich ở đây với một số khác biệt:

Bạn có thể xóa phần tô sáng với <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

Bạn có thể chọn một màu tốt hơn. Chỉ cần đặt cái này lên vimrc của bạn:

hi Cursor guifg=#121212 guibg=#afd700

Đó luôn là một lựa chọn, tôi chỉ muốn xem liệu có thể đặt màu theo ngữ cảnh hay không.
ma08

Tôi không nghĩ đó là hữu ích, nhưng bạn có thể phát hiện nếu mẫu tìm kiếm (trên / hoặc #) giống với từ dưới con trỏ và thay đổi tô sáng Con trỏ
adelarsq

3

Cách duy nhất tôi có thể nghĩ là bằng cách sử dụng CursorMovedCursorMovedIautocmds, chúng được gọi mỗi khi con trỏ được di chuyển ...

Đây là một số mã thực hiện chính xác điều đó:

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

Có một số cảnh báo :

  • Điều này chỉ hoạt động với gVim, vì việc thay đổi màu con trỏ không thể có trong terminal Vim (đây là thứ bạn định cấu hình trong trình giả lập thiết bị đầu cuối của mình và không phải là thứ Vim có thể kiểm soát trong hầu hết các thiết bị đầu cuối).

  • Tôi không thể tìm thấy một cách rõ ràng để kiểm tra xem nhân vật tôi đang tham gia có phải là một phần của cụm từ tìm kiếm hiện tại và / hoặc đang được tô sáng hay không; cách duy nhất là lấy dòng và khai thác lại (một lần nữa) với @/. Có thể có một số khác biệt nhỏ về giải thích biểu thức chính giữa /match()tùy thuộc vào cài đặt của bạn (xem :help match()).

  • Tôi không thể tìm ra cách để kiểm tra xem hiện tại chúng tôi có thực sự làm nổi bật một cái gì đó không, @/đăng ký có chứa tìm kiếm được sử dụng cuối cùng, bất kể chúng tôi đang làm nổi bật cái gì. Vì vậy, những gì tôi đã làm là ánh xạ lại /để đặt g:searchingbiến đầu tiên cho biết chúng tôi đang thực hiện tìm kiếm đang hoạt động và với <C-l>chúng tôi gọi :nohlsearchđể xóa phần tô sáng và đặt g:searchingthành sai để cho biết rằng chúng tôi không tìm kiếm ...

  • Điều này được chạy mỗi khi con trỏ di chuyển , nó có thể không nhanh lắm, đặc biệt là đối với các tệp / dòng lớn, hệ thống chậm hoặc biểu thức phức tạp (mặc dù nó có vẻ hoạt động tốt đối với tôi).


1

Để giữ mọi thứ tối thiểu, nhưng vẫn hoạt động hoàn hảo đối với tôi, tôi có điều này, lấy cảm hứng từ phía trên: làm nổi bật cho đến khi 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>

Bây giờ, nngay cả khi không hlsearchchỉ cho tôi nơi tôi hạ cánh cho đến khi tôi di chuyển con trỏ. Cái SpellRarenày được sử dụng để làm cho nó trở nên dễ rụng hơn khi chỉ có một nhân vật duy nhất khớp với nhau, nếu không thì nó rất mượtIncSearch


0

Tôi đã thử một số câu trả lời khác được liệt kê ở đây và giải pháp ở đây nhưng thấy chúng gây mất tập trung và dễ bị thông báo lỗi. timakro đã viết một plugin giải quyết vấn đề và hoạt động tốt cho tôi cho đến nay.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.