From a3013bef3519d109cc3a00c5279ca91aee12b52b Mon Sep 17 00:00:00 2001 From: Chris Hu Date: Fri, 19 Aug 2016 10:21:59 +0800 Subject: [PATCH] add Mark --- my_configs.vim | 6 + sources_non_forked/Mark/README | 63 +++ sources_non_forked/Mark/plugin/mark.vim | 506 ++++++++++++++++++++++++ 3 files changed, 575 insertions(+) create mode 100644 sources_non_forked/Mark/README create mode 100644 sources_non_forked/Mark/plugin/mark.vim diff --git a/my_configs.vim b/my_configs.vim index 1c9aaba0..2b15bda2 100644 --- a/my_configs.vim +++ b/my_configs.vim @@ -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 diff --git a/sources_non_forked/Mark/README b/sources_non_forked/Mark/README new file mode 100644 index 00000000..194fd3ce --- /dev/null +++ b/sources_non_forked/Mark/README @@ -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. diff --git a/sources_non_forked/Mark/plugin/mark.vim b/sources_non_forked/Mark/plugin/mark.vim new file mode 100644 index 00000000..dfdd0307 --- /dev/null +++ b/sources_non_forked/Mark/plugin/mark.vim @@ -0,0 +1,506 @@ +" Script Name: mark.vim +" Version: 1.1.8 (global version) +" Last Change: April 25, 2008 +" Author: Yuheng Xie +" 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 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('MarkSet', 'n') + if (mapcheck('m', 'n') != "") + nunmap m + endif + nmap m MarkSet +endif +if !hasmapto('MarkSet', 'v') + if (mapcheck('m', 'v') != "") + vunmap m + endif + vmap m MarkSet +endif +if !hasmapto('MarkRegex', 'n') + if (mapcheck('r', 'n') != "") + nunmap r + endif + nmap r MarkRegex +endif +if !hasmapto('MarkRegex', 'v') + if (mapcheck('r', 'v') != "") + vunmap r + endif + vmap r MarkRegex +endif +if !hasmapto('MarkClear', 'n') + if (mapcheck('n', 'n') != "") + nunmap n + endif + nmap n MarkClear +endif + +nnoremap MarkSet :call + \ MarkCurrentWord() +vnoremap MarkSet :call + \ DoMark(GetVisualSelectionEscaped("enV")) +nnoremap MarkRegex :call + \ MarkRegex() +vnoremap MarkRegex :call + \ MarkRegex(GetVisualSelectionEscaped("N")) +nnoremap MarkClear :call + \ DoMark(CurrentMark()) + +" 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 * :call SearchCurrentMark() +nnoremap # :call SearchCurrentMark("b") +nnoremap / :call SearchAnyMark() +nnoremap ? :call SearchAnyMark("b") +nnoremap * :if !SearchNext()execute "norm! *"endif +nnoremap # :if !SearchNext("b")execute "norm! #"endif + +command! -nargs=? Mark call s:DoMark() + +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("") + 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