1
0
Fork 0
mirror of synced 2024-12-24 07:43:20 -05:00
This commit is contained in:
Chris Hu 2016-08-19 10:21:59 +08:00 committed by Huaishun Hu
parent db2bf731a3
commit a3013bef35
3 changed files with 575 additions and 0 deletions

View file

@ -35,4 +35,10 @@ set tabstop=2
set softtabstop=2
set cmdheight=1
set number
" Mark, highlight multiple words
source ~/.vim_runtime/sources_non_forked/Mark/plugin/mark.vim
let g:mwDefaultHighlightingPalette = 'maximum'
let g:mwDefaultHighlightingNum = 10

View file

@ -0,0 +1,63 @@
This is a mirror of http://www.vim.org/scripts/script.php?script_id=1238
This script is written to highlight several words in different colors simultaneously. For example, when you are browsing a big program file, you could highlight some key variables. This will make it easier to trace the source code.
I think this script is functional similar with MultipleSearch vimscript #479.
Usage:
Highlighting:
Normal mode:
\m mark or unmark the word under (or before) the cursor
Place the cursor under the word to be highlighted, press \m, then the word will be colored.
\r manually input a regular expression
To highlight an arbitrary regular expression, press \r and input the regexp.
\n clear this mark (i.e. the mark under the cursor), or clear all highlighted marks
Visual mode:
\m mark or unmark a visual selection
Select some text in Visual mode, press \m, then the selection will be colored.
\r manually input a regular expression (base on the selection text)
Command line:
:Mark regexp to mark a regular expression
:Mark regexp with exactly the same regexp to unmark it
:Mark to clear all marks
Searching:
Normal mode:
* # \* \# \/ \? use these six keys to jump to the other marks
and you could also use VIM's / and ? to search, since the mark patterns have
been added to the search history.
Here is a sumerization of * # \* \# \/ \?:
" First of all, \#, \? and # behave just like \*, \/ and *, respectively,
" except that \#, \? and # search backward.
"
" \*, \/ and *'s behaviors differ base on whether the cursor is currently
" placed over an active mark:
"
" Cursor over mark Cursor not over mark
" ---------------------------------------------------------------------------
" \* jump to the next occurrence of jump to the next occurrence of
" current mark, and remember it "last mark".
" as "last mark".
"
" \/ jump to the next occurrence of same as left
" ANY mark.
"
" * if \* is the most recently used, do VIM's original *
" do a \*; otherwise (\/ is the
" most recently used), do a \/.
Screenshot:
http://elephant.net.cn/files/vim_screenshot.png (It is also the screenshot of my colorscheme vimscript #1253.)
Bugs and Notes:
Some words which have been already colored by syntax scripts could not be highlighted.
mark.vim should be re-sourced after any changing to colors. For example, if you
:set background=dark OR
:colorscheme default
you should
:source PATH_OF_PLUGINS/mark.vim
after that. Otherwise, you won't see the colors.
Unfortunately, it seems that .gvimrc runs after plugin scripts. So if you set any color settings in .gvimrc, you have to add one line to the end of .gvimrc to source mark.vim.

View file

@ -0,0 +1,506 @@
" Script Name: mark.vim
" Version: 1.1.8 (global version)
" Last Change: April 25, 2008
" Author: Yuheng Xie <elephant@linux.net.cn>
" Contributor: Luc Hermitte
"
" Description: a little script to highlight several words in different colors
" simultaneously
"
" Usage: :Mark regexp to mark a regular expression
" :Mark regexp with exactly the same regexp to unmark it
" :Mark to clear all marks
"
" You may map keys for the call in your vimrc file for
" convenience. The default keys is:
" Highlighting:
" Normal \m mark or unmark the word under or before the cursor
" \r manually input a regular expression
" \n clear current mark (i.e. the mark under the cursor),
" or clear all marks
" Visual \m mark or unmark a visual selection
" \r manually input a regular expression
" Searching:
" Normal \* jump to the next occurrence of current mark
" \# jump to the previous occurrence of current mark
" \/ jump to the next occurrence of ANY mark
" \? jump to the previous occurrence of ANY mark
" * behaviors vary, please refer to the table on
" # line 123
" combined with VIM's / and ? etc.
"
" The default colors/groups setting is for marking six
" different words in different colors. You may define your own
" colors in your vimrc file. That is to define highlight group
" names as "MarkWordN", where N is a number. An example could be
" found below.
"
" Bugs: some colored words could not be highlighted
"
" Changes:
"
" 10th Mar 2006, Yuheng Xie: jump to ANY mark
" (*) added \* \# \/ \? for the ability of jumping to ANY mark, even when the
" cursor is not currently over any mark
"
" 20th Sep 2005, Yuheng Xie: minor modifications
" (*) merged MarkRegexVisual into MarkRegex
" (*) added GetVisualSelectionEscaped for multi-lines visual selection and
" visual selection contains ^, $, etc.
" (*) changed the name ThisMark to CurrentMark
" (*) added SearchCurrentMark and re-used raw map (instead of VIM function) to
" implement * and #
"
" 14th Sep 2005, Luc Hermitte: modifications done on v1.1.4
" (*) anti-reinclusion guards. They do not guard colors definitions in case
" this script must be reloaded after .gvimrc
" (*) Protection against disabled |line-continuation|s.
" (*) Script-local functions
" (*) Default keybindings
" (*) \r for visual mode
" (*) uses <leader> instead of "\"
" (*) do not mess with global variable g:w
" (*) regex simplified -> double quotes changed into simple quotes.
" (*) strpart(str, idx, 1) -> str[idx]
" (*) command :Mark
" -> e.g. :Mark Mark.\{-}\ze(
" default colors/groups
" you may define your own colors in you vimrc file, in the form as below:
hi MarkWord1 ctermbg=Cyan ctermfg=Black guibg=#8CCBEA guifg=Black
hi MarkWord2 ctermbg=Green ctermfg=Black guibg=#A4E57E guifg=Black
hi MarkWord3 ctermbg=Yellow ctermfg=Black guibg=#FFDB72 guifg=Black
hi MarkWord4 ctermbg=Red ctermfg=Black guibg=#FF7272 guifg=Black
hi MarkWord5 ctermbg=Magenta ctermfg=Black guibg=#FFB3FF guifg=Black
hi MarkWord6 ctermbg=Blue ctermfg=Black guibg=#9999FF guifg=Black
" Anti reinclusion guards
if exists('g:loaded_mark') && !exists('g:force_reload_mark')
finish
endif
" Support for |line-continuation|
let s:save_cpo = &cpo
set cpo&vim
" Default bindings
if !hasmapto('<Plug>MarkSet', 'n')
if (mapcheck('<leader>m', 'n') != "")
nunmap <leader>m
endif
nmap <unique> <silent> <leader>m <Plug>MarkSet
endif
if !hasmapto('<Plug>MarkSet', 'v')
if (mapcheck('<leader>m', 'v') != "")
vunmap <leader>m
endif
vmap <unique> <silent> <leader>m <Plug>MarkSet
endif
if !hasmapto('<Plug>MarkRegex', 'n')
if (mapcheck('<leader>r', 'n') != "")
nunmap <leader>r
endif
nmap <unique> <silent> <leader>r <Plug>MarkRegex
endif
if !hasmapto('<Plug>MarkRegex', 'v')
if (mapcheck('<leader>r', 'v') != "")
vunmap <leader>r
endif
vmap <unique> <silent> <leader>r <Plug>MarkRegex
endif
if !hasmapto('<Plug>MarkClear', 'n')
if (mapcheck('<leader>n', 'n') != "")
nunmap <leader>n
endif
nmap <unique> <silent> <leader>n <Plug>MarkClear
endif
nnoremap <silent> <Plug>MarkSet :call
\ <sid>MarkCurrentWord()<cr>
vnoremap <silent> <Plug>MarkSet <c-\><c-n>:call
\ <sid>DoMark(<sid>GetVisualSelectionEscaped("enV"))<cr>
nnoremap <silent> <Plug>MarkRegex :call
\ <sid>MarkRegex()<cr>
vnoremap <silent> <Plug>MarkRegex <c-\><c-n>:call
\ <sid>MarkRegex(<sid>GetVisualSelectionEscaped("N"))<cr>
nnoremap <silent> <Plug>MarkClear :call
\ <sid>DoMark(<sid>CurrentMark())<cr>
" Here is a sumerization of the following keys' behaviors:
"
" First of all, \#, \? and # behave just like \*, \/ and *, respectively,
" except that \#, \? and # search backward.
"
" \*, \/ and *'s behaviors differ base on whether the cursor is currently
" placed over an active mark:
"
" Cursor over mark Cursor not over mark
" ---------------------------------------------------------------------------
" \* jump to the next occurrence of jump to the next occurrence of
" current mark, and remember it "last mark".
" as "last mark".
"
" \/ jump to the next occurrence of same as left
" ANY mark.
"
" * if \* is the most recently used, do VIM's original *
" do a \*; otherwise (\/ is the
" most recently used), do a \/.
nnoremap <silent> <leader>* :call <sid>SearchCurrentMark()<cr>
nnoremap <silent> <leader># :call <sid>SearchCurrentMark("b")<cr>
nnoremap <silent> <leader>/ :call <sid>SearchAnyMark()<cr>
nnoremap <silent> <leader>? :call <sid>SearchAnyMark("b")<cr>
nnoremap <silent> * :if !<sid>SearchNext()<bar>execute "norm! *"<bar>endif<cr>
nnoremap <silent> # :if !<sid>SearchNext("b")<bar>execute "norm! #"<bar>endif<cr>
command! -nargs=? Mark call s:DoMark(<f-args>)
autocmd! BufWinEnter * call s:UpdateMark()
" Functions
function! s:MarkCurrentWord()
let w = s:PrevWord()
if w != ""
call s:DoMark('\<' . w . '\>')
endif
endfunction
function! s:GetVisualSelection()
let save_a = @a
silent normal! gv"ay
let res = @a
let @a = save_a
return res
endfunction
function! s:GetVisualSelectionEscaped(flags)
" flags:
" "e" \ -> \\
" "n" \n -> \\n for multi-lines visual selection
" "N" \n removed
" "V" \V added for marking plain ^, $, etc.
let result = s:GetVisualSelection()
let i = 0
while i < strlen(a:flags)
if a:flags[i] ==# "e"
let result = escape(result, '\')
elseif a:flags[i] ==# "n"
let result = substitute(result, '\n', '\\n', 'g')
elseif a:flags[i] ==# "N"
let result = substitute(result, '\n', '', 'g')
elseif a:flags[i] ==# "V"
let result = '\V' . result
endif
let i = i + 1
endwhile
return result
endfunction
" manually input a regular expression
function! s:MarkRegex(...) " MarkRegex(regexp)
let regexp = ""
if a:0 > 0
let regexp = a:1
endif
call inputsave()
let r = input("@", regexp)
call inputrestore()
if r != ""
call s:DoMark(r)
endif
endfunction
" define variables if they don't exist
function! s:InitMarkVariables()
if !exists("g:mwHistAdd")
let g:mwHistAdd = "/@"
endif
if !exists("g:mwCycleMax")
let i = 1
while hlexists("MarkWord" . i)
let i = i + 1
endwhile
let g:mwCycleMax = i - 1
endif
if !exists("g:mwCycle")
let g:mwCycle = 1
endif
let i = 1
while i <= g:mwCycleMax
if !exists("g:mwWord" . i)
let g:mwWord{i} = ""
endif
let i = i + 1
endwhile
if !exists("g:mwLastSearched")
let g:mwLastSearched = ""
endif
endfunction
" return the word under or before the cursor
function! s:PrevWord()
let line = getline(".")
if line[col(".") - 1] =~ '\w'
return expand("<cword>")
else
return substitute(strpart(line, 0, col(".") - 1), '^.\{-}\(\w\+\)\W*$', '\1', '')
endif
endfunction
" mark or unmark a regular expression
function! s:DoMark(...) " DoMark(regexp)
" define variables if they don't exist
call s:InitMarkVariables()
" clear all marks if regexp is null
let regexp = ""
if a:0 > 0
let regexp = a:1
endif
if regexp == ""
let i = 1
while i <= g:mwCycleMax
if g:mwWord{i} != ""
let g:mwWord{i} = ""
let lastwinnr = winnr()
exe "windo syntax clear MarkWord" . i
exe lastwinnr . "wincmd w"
endif
let i = i + 1
endwhile
let g:mwLastSearched = ""
return 0
endif
" clear the mark if it has been marked
let i = 1
while i <= g:mwCycleMax
if regexp == g:mwWord{i}
if g:mwLastSearched == g:mwWord{i}
let g:mwLastSearched = ""
endif
let g:mwWord{i} = ""
let lastwinnr = winnr()
exe "windo syntax clear MarkWord" . i
exe lastwinnr . "wincmd w"
return 0
endif
let i = i + 1
endwhile
" add to history
if stridx(g:mwHistAdd, "/") >= 0
call histadd("/", regexp)
endif
if stridx(g:mwHistAdd, "@") >= 0
call histadd("@", regexp)
endif
" quote regexp with / etc. e.g. pattern => /pattern/
let quote = "/?~!@#$%^&*+-=,.:"
let i = 0
while i < strlen(quote)
if stridx(regexp, quote[i]) < 0
let quoted_regexp = quote[i] . regexp . quote[i]
break
endif
let i = i + 1
endwhile
if i >= strlen(quote)
return -1
endif
" choose an unused mark group
let i = 1
while i <= g:mwCycleMax
if g:mwWord{i} == ""
let g:mwWord{i} = regexp
if i < g:mwCycleMax
let g:mwCycle = i + 1
else
let g:mwCycle = 1
endif
let lastwinnr = winnr()
exe "windo syntax clear MarkWord" . i
" suggested by Marc Weber
" exe "windo syntax match MarkWord" . i . " " . quoted_regexp . " containedin=ALL"
exe "windo syntax match MarkWord" . i . " " . quoted_regexp . " containedin=.*"
exe lastwinnr . "wincmd w"
return i
endif
let i = i + 1
endwhile
" choose a mark group by cycle
let i = 1
while i <= g:mwCycleMax
if g:mwCycle == i
if g:mwLastSearched == g:mwWord{i}
let g:mwLastSearched = ""
endif
let g:mwWord{i} = regexp
if i < g:mwCycleMax
let g:mwCycle = i + 1
else
let g:mwCycle = 1
endif
let lastwinnr = winnr()
exe "windo syntax clear MarkWord" . i
" suggested by Marc Weber
" exe "windo syntax match MarkWord" . i . " " . quoted_regexp . " containedin=ALL"
exe "windo syntax match MarkWord" . i . " " . quoted_regexp . " containedin=.*"
exe lastwinnr . "wincmd w"
return i
endif
let i = i + 1
endwhile
endfunction
" update mark colors
function! s:UpdateMark()
" define variables if they don't exist
call s:InitMarkVariables()
let i = 1
while i <= g:mwCycleMax
exe "syntax clear MarkWord" . i
if g:mwWord{i} != ""
" quote regexp with / etc. e.g. pattern => /pattern/
let quote = "/?~!@#$%^&*+-=,.:"
let j = 0
while j < strlen(quote)
if stridx(g:mwWord{i}, quote[j]) < 0
let quoted_regexp = quote[j] . g:mwWord{i} . quote[j]
break
endif
let j = j + 1
endwhile
if j >= strlen(quote)
continue
endif
" suggested by Marc Weber
" exe "syntax match MarkWord" . i . " " . quoted_regexp . " containedin=ALL"
exe "syntax match MarkWord" . i . " " . quoted_regexp . " containedin=.*"
endif
let i = i + 1
endwhile
endfunction
" return the mark string under the cursor. multi-lines marks not supported
function! s:CurrentMark()
" define variables if they don't exist
call s:InitMarkVariables()
let line = getline(".")
let i = 1
while i <= g:mwCycleMax
if g:mwWord{i} != ""
let start = 0
while start >= 0 && start < strlen(line) && start < col(".")
let b = match(line, g:mwWord{i}, start)
let e = matchend(line, g:mwWord{i}, start)
if b < col(".") && col(".") <= e
let s:current_mark_position = line(".") . "_" . b
return g:mwWord{i}
endif
let start = e
endwhile
endif
let i = i + 1
endwhile
return ""
endfunction
" search current mark
function! s:SearchCurrentMark(...) " SearchCurrentMark(flags)
let flags = ""
if a:0 > 0
let flags = a:1
endif
let w = s:CurrentMark()
if w != ""
let p = s:current_mark_position
call search(w, flags)
call s:CurrentMark()
if p == s:current_mark_position
call search(w, flags)
endif
let g:mwLastSearched = w
else
if g:mwLastSearched != ""
call search(g:mwLastSearched, flags)
else
call s:SearchAnyMark(flags)
let g:mwLastSearched = s:CurrentMark()
endif
endif
endfunction
" combine all marks into one regexp
function! s:AnyMark()
" define variables if they don't exist
call s:InitMarkVariables()
let w = ""
let i = 1
while i <= g:mwCycleMax
if g:mwWord{i} != ""
if w != ""
let w = w . '\|' . g:mwWord{i}
else
let w = g:mwWord{i}
endif
endif
let i = i + 1
endwhile
return w
endfunction
" search any mark
function! s:SearchAnyMark(...) " SearchAnyMark(flags)
let flags = ""
if a:0 > 0
let flags = a:1
endif
let w = s:CurrentMark()
if w != ""
let p = s:current_mark_position
else
let p = ""
endif
let w = s:AnyMark()
call search(w, flags)
call s:CurrentMark()
if p == s:current_mark_position
call search(w, flags)
endif
let g:mwLastSearched = ""
endfunction
" search last searched mark
function! s:SearchNext(...) " SearchNext(flags)
let flags = ""
if a:0 > 0
let flags = a:1
endif
let w = s:CurrentMark()
if w != ""
if g:mwLastSearched != ""
call s:SearchCurrentMark(flags)
else
call s:SearchAnyMark(flags)
endif
return 1
else
return 0
endif
endfunction
" Restore previous 'cpo' value
let &cpo = s:save_cpo
" vim: ts=2 sw=2