Added plugin for highlighting multiple words with different styles.

Source: https://vim.fandom.com/wiki/Highlight_multiple_words
This commit is contained in:
2025-07-11 20:56:22 +09:00
parent 7527d0584f
commit 786956a3fe
3 changed files with 336 additions and 0 deletions
+3
View File
@@ -138,3 +138,6 @@ vim.diagnostic.config({
border = "rounded",
},
})
local highlight_script_path = debug.getinfo(1, "S").source:match("@?(.*[\\/])")
vim.cmd("source " .. highlight_script_path .. "vim/highlight/highlight.vim")
+28
View File
@@ -0,0 +1,28 @@
hlnum,ctermfg,ctermbg,guifg,guibg
1,red,,red,
2,green,,green,
3,blue,,blue,
4,black,magenta,black,IndianRed
5,black,green,black,chartreuse
6,black,cyan,black,DeepSkyBlue
7,white,DarkRed,white,firebrick
8,white,DarkGreen,white,DarkGreen
9,white,DarkBlue,white,DarkSlateBlue
11,,,black,thistle
12,,,black,burlywood
13,,,black,PowderBlue
14,,,black,peru
15,,,black,DarkSeaGreen
16,,,black,SteelBlue
17,,,black,DarkOrange
18,,,black,DarkOliveGreen
19,,,black,SlateGray
21,,,red,grey20
22,,,green,grey20
23,,,CornflowerBlue,grey20
24,,,red,grey40
25,,,green,grey40
26,,,blue,grey40
27,,,red,grey70
28,,,DarkGreen,grey70
29,,,blue,grey70
1 hlnum ctermfg ctermbg guifg guibg
2 1 red red
3 2 green green
4 3 blue blue
5 4 black magenta black IndianRed
6 5 black green black chartreuse
7 6 black cyan black DeepSkyBlue
8 7 white DarkRed white firebrick
9 8 white DarkGreen white DarkGreen
10 9 white DarkBlue white DarkSlateBlue
11 11 black thistle
12 12 black burlywood
13 13 black PowderBlue
14 14 black peru
15 15 black DarkSeaGreen
16 16 black SteelBlue
17 17 black DarkOrange
18 18 black DarkOliveGreen
19 19 black SlateGray
20 21 red grey20
21 22 green grey20
22 23 CornflowerBlue grey20
23 24 red grey40
24 25 green grey40
25 26 blue grey40
26 27 red grey70
27 28 DarkGreen grey70
28 29 blue grey70
+305
View File
@@ -0,0 +1,305 @@
" Plugin to highlight multiple words in different colors.
" Version 2008-11-19 from http://vim.wikia.com/wiki/VimTip1572
" File highlights.csv (in same directory as script) defines the highlights.
"
" Type '\m' to toggle mapping of keypad on/off (assuming \ leader).
" Type '\f' to find the next match; '\F' to find backwards.
" Can also type '\n' or '\N' for search; then n or N will find next.
" On the numeric keypad, press:
" 1 to highlight visually selected text or current word
" using highlight group hl1 (defined below)
" 2 for highlight hl2, 3 for highlight hl3, etc
" (can press 1 to 9 on keypad for highlights hl1 to hl9)
" 0 to remove highlight from current word
" - to remove all highlights in current window
" + to restore highlights cleared with '-' in current window
" * to restore highlights (possibly from another window)
" Can press 1 or 2 on main keyboard before keypad 1..9 for more highlights.
" Commands:
" ':Highlight' list all highlights.
" ':Highlight [n [pattern]]' set highlight.
" ':Hsample' display all highlights in a scratch buffer.
" ':Hclear [hlnum|pattern|*]' clear highlights.
" ':Hsave x', ':Hrestore x' save/restore highlights (x any name).
" Saving current highlights requires '!' in 'viminfo' option.
if v:version < 702 || exists('loaded_highlightmultiple') || &cp
finish
endif
let loaded_highlightmultiple = 1
" On first call, read file highlights.csv in same directory as script.
" For example, line "5,white,blue,black,green" executes:
" highlight hl5 ctermfg=white ctermbg=blue guifg=black guibg=green
let s:data_file = expand('<sfile>:p:r').'.csv'
let s:loaded_data = 0
function! LoadHighlights()
if !s:loaded_data
if filereadable(s:data_file)
let names = ['hl', 'ctermfg=', 'ctermbg=', 'guifg=', 'guibg=']
for line in readfile(s:data_file)
let fields = split(line, ',', 1)
if len(fields) == 5 && fields[0] =~ '^\d\+$'
let cmd = range(5)
call map(cmd, 'names[v:val].fields[v:val]')
call filter(cmd, 'v:val!~''=$''')
execute 'silent highlight '.join(cmd)
endif
endfor
let s:loaded_data = 1
endif
if !s:loaded_data
echo 'Error: Could not read highlight data from '.s:data_file
endif
endif
endfunction
" Return last visually selected text or '\<cword\>'.
" what = 1 (selection), or 2 (cword), or 0 (guess if 1 or 2 is wanted).
function! s:Pattern(what)
if a:what == 2 || (a:what == 0 && histget(':', -1) =~# '^H')
let result = expand("<cword>")
if !empty(result)
let result = '\<'.result.'\>'
endif
else
let old_reg = getreg('"')
let old_regtype = getregtype('"')
normal! gvy
let result = substitute(escape(@@, '\.*$^~['), '\_s\+', '\\_s\\+', 'g')
normal! gV
call setreg('"', old_reg, old_regtype)
endif
return result
endfunction
" Remove any highlighting for hlnum then highlight pattern (if not empty).
" If pat is numeric, use current word or visual selection and
" increase hlnum by count*10 (if count [1..9] is given).
function! s:DoHighlight(hlnum, pat, decade)
call LoadHighlights()
let hltotal = a:hlnum
if 0 < a:decade && a:decade < 10
let hltotal += a:decade * 10
endif
if type(a:pat) == type(0)
let pattern = s:Pattern(a:pat)
else
let pattern = a:pat
endif
let id = hltotal + 100
silent! call matchdelete(id)
if !empty(pattern)
try
call matchadd('hl'.hltotal, pattern, -1, id)
catch /E28:/
echo 'Highlight hl'.hltotal.' is not defined'
endtry
endif
endfunction
" Remove all matches for pattern.
function! s:UndoHighlight(pat)
if type(a:pat) == type(0)
let pattern = s:Pattern(a:pat)
else
let pattern = a:pat
endif
for m in getmatches()
if m.pattern ==# pattern
call matchdelete(m.id)
endif
endfor
endfunction
" Return pattern to search for next match, and do search.
function! s:Search(backward)
let patterns = []
for m in getmatches()
call add(patterns, m.pattern)
endfor
if empty(patterns)
let pat = ''
else
let pat = join(patterns, '\|')
call search(pat, a:backward ? 'b' : '')
endif
return pat
endfunction
" Enable or disable mappings and any current matches.
function! s:MatchToggle()
if exists('g:match_maps') && g:match_maps
let g:match_maps = 0
for i in range(0, 9)
execute 'unmap <k'.i.'>'
endfor
nunmap <kMinus>
nunmap <kPlus>
nunmap <kMultiply>
nunmap <Leader>f
nunmap <Leader>F
nunmap <Leader>n
nunmap <Leader>N
else
let g:match_maps = 1
for i in range(1, 9)
execute 'vnoremap <silent> <k'.i.'> :<C-U>call <SID>DoHighlight('.i.', 1, v:count)<CR>'
execute 'nnoremap <silent> <k'.i.'> :<C-U>call <SID>DoHighlight('.i.', 2, v:count)<CR>'
endfor
vnoremap <silent> <k0> :<C-U>call <SID>UndoHighlight(1)<CR>
nnoremap <silent> <k0> :<C-U>call <SID>UndoHighlight(2)<CR>
nnoremap <silent> <kMinus> :call <SID>WindowMatches(0)<CR>
nnoremap <silent> <kPlus> :call <SID>WindowMatches(1)<CR>
nnoremap <silent> <kMultiply> :call <SID>WindowMatches(2)<CR>
nnoremap <silent> <Leader>f :call <SID>Search(0)<CR>
nnoremap <silent> <Leader>F :call <SID>Search(1)<CR>
nnoremap <silent> <Leader>n :let @/=<SID>Search(0)<CR>
nnoremap <silent> <Leader>N :let @/=<SID>Search(1)<CR>
endif
call s:WindowMatches(g:match_maps)
echo 'Mappings for matching:' g:match_maps ? 'ON' : 'off'
endfunction
nnoremap <silent> <Leader>m :call <SID>MatchToggle()<CR>
" Remove and save current matches, or restore them.
function! s:WindowMatches(action)
call LoadHighlights()
if a:action == 1
if exists('w:last_matches')
call setmatches(w:last_matches)
endif
elseif a:action == 2
if exists('g:last_matches')
call setmatches(g:last_matches)
else
call s:Hrestore('')
endif
else
let m = getmatches()
if !empty(m)
let w:last_matches = m
let g:last_matches = m
call s:Hsave('')
call clearmatches()
endif
endif
endfunction
" Return name of global variable to save value ('' if invalid).
function! s:NameForSave(name)
if a:name =~# '^\w*$'
return 'HI_SAVE_'.toupper(a:name)
endif
echo 'Error: Invalid name "'.a:name.'"'
return ''
endfunction
" Return custom completion string (match patterns).
function! s:MatchPatterns(A, L, P)
return join(sort(map(getmatches(), 'v:val.pattern')), "\n")
endfunction
" Return custom completion string (saved highlight names).
function! s:SavedNames(A, L, P)
let l = filter(keys(g:), 'v:val =~# ''^HI_SAVE_\w''')
return tolower(join(sort(map(l, 'strpart(v:val, 8)')), "\n"))
endfunction
" Save current highlighting in a global variable.
function! s:Hsave(name)
let sname = s:NameForSave(a:name)
if !empty(sname)
let l = getmatches()
call map(l, 'join([v:val.group, v:val.pattern, v:val.priority, v:val.id], "\t")')
let g:{sname} = join(l, "\n")
endif
endfunction
command! -nargs=? -complete=custom,s:SavedNames Hsave call s:Hsave('<args>')
" Restore current highlighting from a global variable.
function! s:Hrestore(name)
call LoadHighlights()
let sname = s:NameForSave(a:name)
if !empty(sname)
if exists('g:{sname}')
let matches = []
for l in split(g:{sname}, "\n")
let f = split(l, "\t", 1)
call add(matches, {'group':f[0], 'pattern':f[1], 'priority':f[2], 'id':f[3]})
endfor
call setmatches(matches)
else
echo 'No such global variable: '.sname
endif
endif
endfunction
command! -nargs=? -complete=custom,s:SavedNames Hrestore call s:Hrestore('<args>')
" Clear a match, or clear all current matches. Example args:
" '14' = hl14, '*' = all, '' = visual selection or cword,
" 'pattern' = all matches for pattern
function! s:Hclear(pattern) range
if empty(a:pattern)
call s:UndoHighlight(0)
elseif a:pattern == '*'
call s:WindowMatches(0)
elseif a:pattern =~ '^[1-9][0-9]\?$'
call s:DoHighlight(str2nr(a:pattern), '', 0)
else
call s:UndoHighlight(a:pattern)
endif
endfunction
command! -nargs=* -complete=custom,s:MatchPatterns -range Hclear call s:Hclear('<args>')
" Create a scratch buffer with sample text, and apply all highlighting.
function! s:Hsample()
call LoadHighlights()
new
setlocal buftype=nofile bufhidden=hide noswapfile
let lines = []
let items = []
for hl in filter(range(1, 99), 'v:val % 10 > 0')
if hlexists('hl'.hl)
let sample = printf('Sample%2d', hl)
call s:DoHighlight(hl, sample, 0)
else
let sample = ' '
endif
call add(items, sample)
if len(items) >= 3
call insert(lines, substitute(join(items), '\s\+$', '', ''))
let items = []
endif
endfor
call append(0, filter(lines, 'len(v:val) > 0'))
$d
%s/\d3$/&\r/e
endfunction
command! Hsample call s:Hsample()
" Set a match, or display all current matches. Example args:
" '14' = set hl14 for visual selection or cword,
" '14 pattern' = set hl14 for pattern, '' = display all
function! s:Highlight(args) range
if empty(a:args)
echo 'Highlight groups and patterns:'
for m in getmatches()
echo m.group m.pattern
endfor
return
endif
let l = matchlist(a:args, '^\s*\([1-9][0-9]\?\)\%($\|\s\+\(.*\)\)')
if len(l) >= 3
let hlnum = str2nr(l[1])
let pattern = l[2]
if empty(pattern)
let pattern = s:Pattern(0)
endif
call s:DoHighlight(hlnum, pattern, 0)
return
endif
echo 'Error: First argument must be highlight number 1..99'
endfunction
command! -nargs=* -range Highlight call s:Highlight('<args>')