ด้วย colourscheme ปัจจุบันที่ฉันใช้มันยากที่จะหาตำแหน่งที่เคอร์เซอร์วางไว้เมื่อนำทางผ่านผลการค้นหา สีที่ไฮไลต์และสีของเคอร์เซอร์ผสมกันทำให้หาเคอร์เซอร์ได้ยาก
ฉันจะตั้งค่าสีเคอร์เซอร์ได้อย่างไรเมื่ออยู่ในคำที่เน้นสี
ด้วย colourscheme ปัจจุบันที่ฉันใช้มันยากที่จะหาตำแหน่งที่เคอร์เซอร์วางไว้เมื่อนำทางผ่านผลการค้นหา สีที่ไฮไลต์และสีของเคอร์เซอร์ผสมกันทำให้หาเคอร์เซอร์ได้ยาก
ฉันจะตั้งค่าสีเคอร์เซอร์ได้อย่างไรเมื่ออยู่ในคำที่เน้นสี
คำตอบ:
ฉันใช้ตัวอย่างนี้จากคำปราศรัยที่ยอดเยี่ยมของ 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
ในเวลาอื่น (เช่นเมื่อเคอร์เซอร์เคลื่อนที่)
ฉันเพิ่งเขียนเวอร์ชันขั้นสูงเพิ่มเติมนี้เพื่อตอบคำถามอื่น มันมีการเปลี่ยนแปลงดังต่อไปนี้ ::
n
อีกครั้งเพื่อข้ามไปยังการแข่งขันถัดไป) สิ่งนี้ช่วยให้คุณสามารถตั้งเวลาได้นานขึ้นเป็นกลุ่ม-searchhiปลั๊กอินมีคุณลักษณะที่ร้องขอเดิม
ตามคำตอบของ 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>
คุณสามารถเลือกสีที่ดีกว่า เพียงแค่ใส่สิ่งนี้ไว้ใน vimrc ของคุณ:
hi Cursor guifg=#121212 guibg=#afd700
วิธีเดียวที่ฉันคิดได้คือใช้CursorMoved
และCursorMovedI
autocmds สิ่งเหล่านี้จะถูกเรียกใช้ทุกครั้งที่เคอร์เซอร์ถูกย้าย ...
นี่คือรหัสบางส่วนที่ทำสิ่งนั้นอย่างแน่นอน:
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 ที่ซับซ้อน (ดูเหมือนว่าจะใช้ได้ดีสำหรับฉัน)
เพื่อให้สิ่งต่าง ๆ น้อยที่สุด แต่ก็ยังทำงานได้อย่างสมบูรณ์แบบสำหรับฉันฉันได้รับแรงบันดาลใจจากด้านบน: ไฮไลท์ธรรมดาจนถึง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