ตั้งค่าสีเคอร์เซอร์ที่แตกต่างกันเมื่อใช้คำที่เน้น


19

ด้วย colourscheme ปัจจุบันที่ฉันใช้มันยากที่จะหาตำแหน่งที่เคอร์เซอร์วางไว้เมื่อนำทางผ่านผลการค้นหา สีที่ไฮไลต์และสีของเคอร์เซอร์ผสมกันทำให้หาเคอร์เซอร์ได้ยาก

ฉันจะตั้งค่าสีเคอร์เซอร์ได้อย่างไรเมื่ออยู่ในคำที่เน้นสี

สกรีนช็อตของปัญหา

คำตอบ:


14

ฉันใช้ตัวอย่างนี้จากคำปราศรัยที่ยอดเยี่ยมของ Damian Conway, More Morely Vim (ที่ 4m 59s) ทำให้ไฮไลท์ทั้งหมดกะพริบในเวลาสั้น ๆ เมื่อคุณกระโดดข้ามผลการค้นหา

" 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ในเวลาอื่น (เช่นเมื่อเคอร์เซอร์เคลื่อนที่)

UPDATE:

ฉันเพิ่งเขียนเวอร์ชันขั้นสูงเพิ่มเติมนี้เพื่อตอบคำถามอื่น มันมีการเปลี่ยนแปลงดังต่อไปนี้ ::

  1. (ไม่บังคับ) กระพริบซ้ำ ๆ : เวอร์ชั่นดั้งเดิมของ Conway จะกะพริบเพียงครั้งเดียว: เปิดแล้วปิด
  2. ช่วยให้คุณสามารถขัดจังหวะการกะพริบได้โดยพิมพ์คำสั่งอื่น ๆ (เช่นการกดnอีกครั้งเพื่อข้ามไปยังการแข่งขันถัดไป) สิ่งนี้ช่วยให้คุณสามารถตั้งเวลาได้นานขึ้น

อัปเดต 2:

เป็นกลุ่ม-searchhiปลั๊กอินมีคุณลักษณะที่ร้องขอเดิม


ใช้งานได้ดี ฉันจะใช้สิ่งนี้ต่อจากนี้ ฉันจะพยายามที่จะใช้ถาวรหนึ่งในภายหลัง
ma08

2 บรรทัดแรกทำอะไร เท่าที่ฉันเห็นตัวแปรที่กำหนดไม่ได้ถูกใช้และถ้าฉันลบบรรทัดเหล่านั้นออกไปมันก็ยังใช้งานได้
Martin Tournoij

@Carpetsmoker บรรทัดเหล่านั้น (ตอนนี้ลบ) เป็น cruft ล้าสมัยที่ดี หากคุณดูการพูดคุยคุณจะเห็นว่า Conway มาถึงวิธีนี้หลังจากทำซ้ำสองสามครั้ง ตัวแปรที่ไม่จำเป็นถูกใช้ในการเปลี่ยนแปลงก่อนหน้านี้ แต่ไม่ได้อยู่ในตัวแปรนี้ ฉันคัดลอกมันไปไว้ใน. vimrc ของฉันก่อนที่ฉันจะเริ่มเรียนรู้ vimscript และเห็นได้ชัดว่าไม่เคยดูรหัสอีกแม้ว่าจะวางลงในคำตอบของฉัน! เห็นดี
รวย

ฉันเพิ่งแทนที่เสียงเรียกเข้าแบบชีพจร (ฉันคิดว่ามันถูกเรียกว่า) addon ด้วยตัวอย่างนี้และมันจะดีกว่า / เร็วกว่ามาก
craigp

@ แบดเจอร์ดีใจที่ได้ยิน :)
Rich

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 สามารถควบคุมได้ในเทอร์มินัลส่วนใหญ่)

  • ฉันไม่พบวิธีที่ชัดเจนในการตรวจสอบว่าอักขระที่ฉันใช้อยู่เป็นส่วนหนึ่งของคำค้นหาปัจจุบันและ / หรือกำลังถูกไฮไลต์อยู่หรือไม่ วิธีเดียวที่จะได้รับสายและ regexp ว่า (อีกครั้ง) @/กับ อาจมีความแตกต่างเล็กน้อยในการตีความ regexp ระหว่าง/และmatch()ขึ้นอยู่กับการตั้งค่าของคุณ (ดู:help match())

  • ฉันไม่สามารถหาวิธีตรวจสอบว่าเรากำลังไฮไลต์บางสิ่งบางอย่างอยู่หรือไม่การ@/ลงทะเบียนมีการค้นหาที่ใช้ครั้งล่าสุดโดยไม่คำนึงถึงสิ่งที่เรากำลังเน้น ดังนั้นสิ่งที่ฉันทำคือทำการแมปใหม่/เพื่อตั้งค่าg:searchingตัวแปรแรกเพื่อระบุว่าเราทำการค้นหาที่ใช้งานอยู่และด้วยการที่<C-l>เราโทร:nohlsearchเพื่อล้างการเน้นและตั้งค่าg:searchingเป็นเท็จเพื่อระบุว่าเราไม่ได้ค้นหา ...

  • การดำเนินการนี้ทุกครั้งที่เคอร์เซอร์เคลื่อนที่อาจไม่เร็วมากโดยเฉพาะอย่างยิ่งสำหรับไฟล์ / บรรทัดขนาดใหญ่ระบบช้าหรือ regexps ที่ซับซ้อน (ดูเหมือนว่าจะใช้ได้ดีสำหรับฉัน)


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.