diff --git a/.vim/plugin/ScrollColor.vim b/.vim/plugin/ScrollColor.vim deleted file mode 100644 index 7c4960c..0000000 --- a/.vim/plugin/ScrollColor.vim +++ /dev/null @@ -1,457 +0,0 @@ -" ScrollColors.vim - Colorsheme Scroller, Chooser, and Browser -" -" Author and maintainer: Yakov Lerner -" Last Change: 2006-07-18 -" -" SYNOPSIS: -" This is colorscheme Scroller/Chooser/Browser. -" With this plugin, you walk through installed -" colorschemes using arrow keys. -" -" SHORT USAGE DESCRIPTION: -" Drop ScrollColors.vim into your plugin directory. -" Type :SCROLL -" Use arrow keys to walk through colorschemes, ? for help, Esc to exit. -" -" DETAILED DESCRIPTION: -" 1. source ScrollColors.vim " or drop ScrollColors.vim into -" " your ~/.vim/plugins directory -" 2. Type :SCROLL -" 3. Use arrows to scroll thgough colorschemes. -" 4. When done, press Esc to exit. You will be prompted -" wether to -" -" You can download 140 colorschemes pack from: -" http://www.vim.org/scripts/script.php?script_id=625 -" Having 140 installed colorschemes is in no way prerequisite for -" ScrollColors. But with ScrollColors you can preview 140 colorschemes -" in couple of minutes. -" -" CUSTOM KEY MAPPINGS: -" You can map two keys of your choice to NextColor and PrevColor actions. -" Choose pair of shortcut keys (for example and , or \n and \p) -" and map them as follows: -" map :NEXTCOLOR -" map :PREVCOLOR - - -if exists("g:scroll_colors") | finish | endif -let g:scroll_colors = 1 - -command! COLORSCROLL :call s:ColorScroller() -command! SCROLLCOLOR :call s:ColorScroller() -command! NEXTCOLOR :call s:NextColorscheme() -command! PREVCOLOR :call s:PrevColorscheme() - -" Example of convenience mappings: -"map :NEXTCOLOR -"map :PREVCOLOR -"map :SCROLLCOLOR - -function! s:ScrollerHelp() - echo " " - echohl Title - echo "Color Scroller Help:" - echo "--------------------" - echohl NONE - echo "Arrows - change colorscheme" - echo "Esc,q,Enter - exit" - echo "h,j,k,l - change colorscheme" - echo "0,g - go to first colorscheme" - echo "$,G - go to last colorscheme" - echo "L - list colorschemes" - echo "PgUp,PgDown - jump by 10 colorschemes" - echo "# - go to colorscheme by index (1-N)" - echo "R - refresh colorscheme list" - echo "? - this help text" - echohl MoreMsg - echo "Press any key to continue" - echohl NONE - call getchar() -endfu - -function! s:Align(s, width) - if strlen(a:s) >= a:width - return a:s." " - else - let pad=" " - let res=a:s - while strlen(res) < a:width - let chunk = (a:width - strlen(res) > strlen(pad) ? strlen(pad) : a:width - strlen(res)) - let res = res . strpart(pad,0,chunk) - endw - return res - endif -endfu - -function! s:ListColors() - echo " " - let list=s:GetColorschemesList() - let width=18 - let pos=0 - while list != '' - let str=substitute(list,"\n.*","","") - let list=substitute(list,"[^\n]*\n", "", "") - let aligned = s:Align(str, width) - if( pos+strlen(aligned)+1 >= &columns) - echo " " - let pos=0 - endif - echon aligned - let pos = pos + strlen(aligned) - endw - echo "Press any key to continue" - call getchar() -endfu - -function! s:CurrentColor() - return exists("g:colors_name") ? g:colors_name : "" -endfu - -function! s:SetColor(name) - exe "color ".a:name - " if we do not assign a:colors_name, then - " bad things happen if file colors/name.vim conmtains wrong assignment inside. - " Wrong assignment inside happens when file was copied but - " assignment inside not fixed. - " Such wrong assignment cause up erratic switches unless - " we do our own assignment to g:colors_name - let g:colors_name=a:name -endfu - -function! s:JumpByIndex(list,total) - let ans = input("Enter colorscheme number (1-".a:total.") : ") - let index = (ans<=0? 1 : 1+(ans-1)%a:total ) - let name = s:EntryByIndex(a:list, index ) - call s:SetColor(name) -endfu - -function! s:JumpByIndex2(list,total, index) - let mod = (a:index <= 0? 1 : 1+(a:index-1)%a:total ) - let name = s:EntryByIndex(a:list, mod ) - call s:SetColor(name) -endfu - -function! s:ExitDialog(old, action) - let ans = 0 - - if a:old == s:CurrentColor() - let ans=1 - elseif a:action == '' - let ans = confirm("Keep this colorscheme ?", "&Yes\n&No\n&Cancel") - elseif action == 'keep' - ans = 1 - elseif action == 'revert' - ans = 2 - endif - - if ans == 1 || ans==0 - " exit, keep colorscheme - let msg = (a:old == s:CurrentColor() ? '' : "(original: '".a:old."')") - call s:FinalEcho( msg ) - elseif ans == 2 - " exit, revert colorscheme - call s:SetColor(a:old) - call s:FinalEcho('original color restored') - elseif ans == 3 - " do not exit, continue browsing - return -1 - endif -endfu - -function! s:ColorScroller() - let old = s:CurrentColor() - let list = s:GetColorschemesList() - let total = s:CountEntries(list) - let loop=0 - - if line("$") == 1 && getline(1) == "" && bufnr('$')==1 - " if buffer is empty, open something - echo "We will open sample text with syntax highlighting." - echo "Watch for the guiding prompt in the bottom line." - echo "When the text will open, use Arrow keys to switch colorschemes, ? for help." - echo " " - echo "Press any key to continue" - call getchar() - :e $VIMRUNTIME/syntax/abc.vim - :setlocal ro - syntax on - redraw - endif - - if !exists("g:syntax_on") - syntax on - redraw - endif - - while 1 - redraw - let index = s:FindIndex(list, s:CurrentColor()) - echo "[" - echohl Search - echon s:CurrentColor() - echohl NONE - if loop == 0 - echon "] ColorScroller: " - echohl MoreMsg | echon "Arrows" | echohl NONE | echon "-next/prev; " - echohl MoreMsg | echon "Esc" | echohl NONE | echon "-exit; " - echohl MoreMsg | echon "?" | echohl NONE | echon "-help > " - else - echon "] " - echon " " . index . "/" . total . " " - echon s:Align("", 12-strlen(s:CurrentColor())) - echon "> ColorScroll > " - echon "Arrows,Esc,? > " - endif - let key = getchar() - let c = nr2char(key) - - if key == "\" || key == "\" || c ==# 'h' || c ==# 'j' - call s:PrevSilent() - elseif key == "\" || key == "\" || c ==# 'l' || c==# 'k' || c==# ' ' - call s:NextSilent() - elseif c==# 'g' || c=='0' || c=='1' - call s:SetColor( s:GetFirstColors() ) - elseif c=='$' || c==# 'G' - call s:SetColor( s:GetLastColors() ) - elseif c ==# 'L' - " command 'L' list colors - call s:ListColors() - elseif c=='Z' || c=='z' || key == 13 || c=='q' || c=='Q' || c==':' || key == 27 - if s:ExitDialog(old, '') != -1 - break - endif - elseif key == 12 " c=="\" - redraw - elseif c == '#' - call s:JumpByIndex(list,total) - elseif key == "\" - call s:JumpByIndex2(list,total, (index-10>=1 ? index-10 : index-10+total)) - elseif key == "\" - call s:JumpByIndex2(list,total, index+10) - elseif c == '?' - call s:ScrollerHelp() - elseif c == 'R' - call s:RefreshColorschemesList() - echo "Colorscheme list refreshed. Press any key to continue." - call getchar() - else - call s:ScrollerHelp() - endif - let loop = loop + 1 - endw -endfu - -" Get 1-based index of 'entry' in \n-separated 'list' -function! s:FindIndex(list,entry) - " we assume entry has no special chars or we could escape() it - let str = substitute("\n" . a:list . "\n", "\n" . a:entry . "\n.*$", "", "") - return 1 + s:CountEntries(str) -endfu - -" Get list element by 1-based index -function! s:EntryByIndex(list,index) - let k=1 - let tail=a:list - while tail != '' && k < a:index - let tail=substitute(tail, "^[^\n]*\n", "", "") - let k = k + 1 - endw - let tail = substitute(tail, "\n.*$", "", "") - return tail -endfu - -function! s:MakeWellFormedList(list) - - " make sure last \n is present - let str=a:list."\n" - " make sure leading \n are not present - let str=substitute(str, "^\n*", "", "") - " make sure entries are separated by exactly one \n - let str=substitute(str, "\n\\+", "\n", "g") - - return str -endfu - -function! s:CountEntries(list) - let str = s:MakeWellFormedList(a:list) - - let str=substitute(str, "[^\n]\\+\n", ".", "g") - - return strlen(str) -endfu - -function! s:RemoveDuplicates(list) - let sep = "\n" - let res = s:MakeWellFormedList(a:list . "\n") - let beg = 0 - while beg < strlen(res) - let end = matchend(res, sep, beg) - let str1 = strpart( res, beg, end - beg) - let res = strpart(res,0,end) . substitute("\n".strpart(res,end), "\n".str1,"\n","g") - let res = substitute(res, "\n\\+", "\n", "g") - let beg = end - endw - return res -endfu - -if v:version >= 700 - -" s:SortVar(): sort components of string @var separated -" by delimiter @sep, and returns the sorted string. -" For example, s:SortVar("c\nb\na", "\n") returns "a\nb\nc\n" -function! s:SortVar(list, sep) - let list = split( a:list, a:sep ) - let sorted = sort(list) - let result = join( sorted, "\n" ) - return result . "\n" -endfun - -endif - -if v:version < 700 -" s:SortVar(): sort components of string @var separated -" by delimiter @sep, and returns the sorted string. -" For example, s:SortVar("c\nb\na", "\n") returns "a\nb\nc\n" -function! s:SortVar(list, sep) - - let res=s:MakeWellFormedList(a:list . "\n") - while 1 - let disorder=0 - let index1=0 - - let len=strlen(res) - while 1 - let index2=matchend(res, a:sep, index1) - if index2 == -1 || index2>=len - break - endif - let index3=matchend(res, a:sep, index2) - if index3 == -1 - let index3=len - endif - let str1=strpart(res, index1, index2-index1) - let str2=strpart(res, index2, index3-index2) - if str1 > str2 - let disorder=1 - " swap str1 and str2 in res - let res=strpart(res,0,index1).str2.str1.strpart(res,index3) - let index1=index1 + strlen(str2) - else - let index1=index1 + strlen(str1) - endif - endw - - if !disorder - break - endif - endw - return res -endfu -endif " v:version < 700 - -let s:list = "" - -function! s:GetColorschemesList() - if s:list == "" - let s:list = s:RefreshColorschemesList() - endif - return s:list -endfunction - - -function! s:RefreshColorschemesList() - let x=globpath(&rtp, "colors/*.vim") - let y=substitute(x."\n","\\(^\\|\n\\)[^\n]*[/\\\\]", "\n", "g") - let z=substitute(y,"\\.vim\n", "\n", "g") - let sorted = s:SortVar(z, "\n") - let s:list = s:RemoveDuplicates(sorted) - return s:list -endfun - -function! s:GetFirstColors() - let list=s:GetColorschemesList() - let trim=substitute(list, "^\n\\+", "", "") - return substitute(trim, "\n.*", "", "") -endfu - -function! s:GetLastColors() - let list=s:GetColorschemesList() - let trim=substitute(list, "\n\\+$", "", "") - return substitute(trim, "^.*\n", "", "") -endfu - -function! s:FinalEcho(suffix) - let list = s:GetColorschemesList() - let total = s:CountEntries(list) - let index = s:FindIndex(list, s:CurrentColor()) - - redraw - echon "[" - echohl Search - echon s:CurrentColor() - echohl NONE - echon "] colorscheme #".index ." of " . total.". " - echon a:suffix -endfu - -function! s:GetNextColor(color) - let list=s:GetColorschemesList() - if ("\n".list) =~ ("\n".s:CurrentColor()."\n") - let next=substitute("\n".list."\n", ".*\n".a:color."\n", "", "") - let next = substitute(next, "\n.*", "", "") - return next=='' ? s:GetFirstColors() : next - else - return s:GetFirstColors() - endif -endfu - -function! s:GetPrevColor(color) - let list=s:GetColorschemesList() - if ("\n".list) =~ ("\n".a:color."\n") - let prev=substitute("\n".list."\n", "\n".a:color."\n.*", "", "") - let prev=substitute(prev, "^.*\n", "", "") - return prev=='' ? s:GetLastColors() : prev - else - return s:GetLastColors() - endif -endfu - -function! s:NextSilent() - let old = s:CurrentColor() - let next = s:GetNextColor(s:CurrentColor()) - call s:SetColor( next ) -endfu - -function! s:PrevSilent() - let old = s:CurrentColor() - let prev = s:GetPrevColor(s:CurrentColor()) - call s:SetColor( prev ) -endfu - -function! s:NextColorscheme() - let old = s:CurrentColor() - let next = s:GetNextColor(s:CurrentColor()) - call s:SetColor( next ) - redraw - call s:FinalEcho('previous: '.old) -endfun - -function! s:PrevColorscheme() - let old = s:CurrentColor() - let prev = s:GetPrevColor(s:CurrentColor()) - call s:SetColor( prev ) - redraw - call s:FinalEcho('previous: '.old) -endfun - -command! CN :call s:NextColorscheme() -command! CP :call s:PrevColorscheme() -map \n :CN -map \p :CP -map \c :echo g:colors_name - -" 2006-07-18 fixed bug with Align() -> s:Align() (affected L command) -" 2006-07-18 added colorlist cache (s:list) -" 2006-07-18 added R key to refresh colorlist -" 2006-07-19 for vim7, sort using builtin sort() (bubblesort is slow) diff --git a/.vim/plugin/mark.vim b/.vim/plugin/mark.vim new file mode 100644 index 0000000..69258e1 --- /dev/null +++ b/.vim/plugin/mark.vim @@ -0,0 +1,638 @@ +" Script Name: mark.vim +" Version: 1.2.2 (global version) +" Last Change: January 30, 2019 +" 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 mute all marks +" :Mark to show all marks again +" +" You may map keys for the call in your vimrc file for +" convenience. The default keys is: +" Highlighting: +" Normal \m mark/unmark the word under the cursor, +" it clear all marks if state is muted +" \n unmark the mark under the cursor, +" or mute/show all marks +" \r manually input a regular expression +" Visual \m mark/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 SEARCHING +" combined with VIM's / and ? etc. +" +" Colors: 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 (on vim < 7.1) +" +" Changes: +" 30th Jan 2019, Yuheng Xie: default to muted when vim restarts +" +" 27th Jan 2019, Yuheng Xie: fix multi-lines pattern +" +" 14th Jan 2019, Yuheng Xie: +" (*) \n now mutes marks instead of clearing them, \m may clear them +" (*) marks are now savable if '!' exists in 'viminfo' +" +" 09th Jan 2019, Yuheng Xie: fix unnamed-register content after visual marking +" +" 21th Nov 2017, Yuheng Xie: fix error when no marks found +" (*) added exists() check when no marks found +" (*) changed default mark colors again +" +" 17th Dec 2016, Yuheng Xie: fix error in vim 6.4 +" (*) added exists() check before calling vim 7 functions +" (*) changed default mark colors +" +" 16th Jan 2015, Yuheng Xie: add auto event WinEnter +" (*) added auto event WinEnter for reloading highlights after :split, etc. +" +" 29th Jul 2014, Yuheng Xie: call matchadd() +" (*) added call to VIM 7.1 matchadd(), make highlighting keywords possible +" +" 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( + +function! s:RGB(r, g, b) + return a:r * 36 + a:g * 6 + a:b + 16 +endfunction + +" default colors/groups +" you may define your own colors in you vimrc file, in the form as below: +if &t_Co < 256 + hi MarkWord1 guifg=White ctermfg=White guibg=#FF0000 ctermbg=Red + hi MarkWord2 guifg=Black ctermfg=Black guibg=#FFD700 ctermbg=Yellow + hi MarkWord3 guifg=Black ctermfg=Black guibg=#5FD700 ctermbg=Green + hi MarkWord4 guifg=Black ctermfg=Black guibg=#00D7FF ctermbg=Cyan + hi MarkWord5 guifg=White ctermfg=White guibg=#0087FF ctermbg=Blue + hi MarkWord6 guifg=White ctermfg=White guibg=#AF00FF ctermbg=Magenta +else + exec "hi MarkWord1 guifg=White ctermfg=White guibg=#FF0000 ctermbg=".s:RGB(5,0,0) + exec "hi MarkWord2 guifg=Black ctermfg=Black guibg=#FFD700 ctermbg=".s:RGB(5,4,0) + exec "hi MarkWord3 guifg=Black ctermfg=Black guibg=#5FD700 ctermbg=".s:RGB(1,4,0) + exec "hi MarkWord4 guifg=Black ctermfg=Black guibg=#00D7FF ctermbg=".s:RGB(0,4,5) + exec "hi MarkWord5 guifg=White ctermfg=White guibg=#0087FF ctermbg=".s:RGB(0,2,5) + exec "hi MarkWord6 guifg=White ctermfg=White guibg=#AF00FF ctermbg=".s:RGB(3,0,5) +endif + +" 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') + nmap m MarkSet +endif +if !hasmapto('MarkSet', 'v') + vmap m MarkSet +endif +if !hasmapto('MarkRegex', 'n') + nmap r MarkRegex +endif +if !hasmapto('MarkRegex', 'v') + vmap r MarkRegex +endif +if !hasmapto('MarkClear', 'n') + 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()) + +" SEARCHING +" +" 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,WinEnter * call s:UpdateMark() + +" Functions + +function! s:MarkCurrentWord() + let w = s:PrevWord() + if w != "" + call s:DoMark('\<' . w . '\>') + endif +endfunction + +function! s:GetVisualSelection() + let save_unamed = getreg('"') + silent normal! gv""y + let res = getreg('"') + call setreg('"', save_unamed) + 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:mw_state") + let g:mw_state = 0 + endif + if !exists("g:MW_HIST_ADD") + let g:MW_HIST_ADD = "/@" + endif + if !exists("g:MW_CYCLE_MAX") + let i = 1 + while hlexists("MarkWord" . i) + let i = i + 1 + endwhile + let g:MW_CYCLE_MAX = i - 1 + endif + if !exists("g:MW_CYCLE") + let g:MW_CYCLE = 1 + endif + let i = 1 + while i <= g:MW_CYCLE_MAX + if !exists("g:MW_WORD" . i) + let g:MW_WORD{i} = "" + endif + let i = i + 1 + endwhile + if !exists("g:MW_LAST_SEARCHED") + let g:MW_LAST_SEARCHED = "" + 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 g:mw_state is 0 (i.e. muted) and regexp is not null + let regexp = "" + if a:0 > 0 + let regexp = a:1 + endif + if regexp == "" + let g:mw_state = 1 - g:mw_state + call s:UpdateMark() + if g:mw_state >= 1 + echo "" + else + echo "MarkWord muted" + endif + return 0 + elseif g:mw_state <= 0 && regexp != "" + let g:mw_state = 1 + echo "" + let i = 1 + while i <= g:MW_CYCLE_MAX + if g:MW_WORD{i} != "" + let g:MW_WORD{i} = "" + let lastwinnr = winnr() + if exists("*winsaveview") + let winview = winsaveview() + endif + if exists("*matchdelete") + windo silent! call matchdelete(3333 + i) + else + exe "windo syntax clear MarkWord" . i + endif + exe lastwinnr . "wincmd w" + if exists("*winrestview") + call winrestview(winview) + endif + endif + let i = i + 1 + endwhile + endif + + " clear the mark if it has been marked + let i = 1 + while i <= g:MW_CYCLE_MAX + if regexp == g:MW_WORD{i} + if g:MW_LAST_SEARCHED == g:MW_WORD{i} + let g:MW_LAST_SEARCHED = "" + endif + let g:MW_WORD{i} = "" + let lastwinnr = winnr() + if exists("*winsaveview") + let winview = winsaveview() + endif + if exists("*matchdelete") + windo silent! call matchdelete(3333 + i) + else + exe "windo syntax clear MarkWord" . i + endif + exe lastwinnr . "wincmd w" + if exists("*winrestview") + call winrestview(winview) + endif + return 0 + endif + let i = i + 1 + endwhile + + " add to history + if stridx(g:MW_HIST_ADD, "/") >= 0 + call histadd("/", regexp) + endif + if stridx(g:MW_HIST_ADD, "@") >= 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:MW_CYCLE_MAX + if g:MW_WORD{i} == "" + let g:MW_WORD{i} = regexp + if i < g:MW_CYCLE_MAX + let g:MW_CYCLE = i + 1 + else + let g:MW_CYCLE = 1 + endif + let lastwinnr = winnr() + if exists("*winsaveview") + let winview = winsaveview() + endif + if exists("*matchadd") + windo silent! call matchdelete(3333 + i) + windo silent! call matchadd("MarkWord" . i, g:MW_WORD{i}, -10, 3333 + i) + else + exe "windo syntax clear MarkWord" . i + " suggested by Marc Weber, use .* instead off ALL + exe "windo syntax match MarkWord" . i . " " . quoted_regexp . " containedin=.*" + endif + exe lastwinnr . "wincmd w" + if exists("*winrestview") + call winrestview(winview) + endif + return i + endif + let i = i + 1 + endwhile + + " choose a mark group by cycle + let i = 1 + while i <= g:MW_CYCLE_MAX + if g:MW_CYCLE == i + if g:MW_LAST_SEARCHED == g:MW_WORD{i} + let g:MW_LAST_SEARCHED = "" + endif + let g:MW_WORD{i} = regexp + if i < g:MW_CYCLE_MAX + let g:MW_CYCLE = i + 1 + else + let g:MW_CYCLE = 1 + endif + let lastwinnr = winnr() + if exists("*winsaveview") + let winview = winsaveview() + endif + if exists("*matchadd") + windo silent! call matchdelete(3333 + i) + windo silent! call matchadd("MarkWord" . i, g:MW_WORD{i}, -10, 3333 + i) + else + exe "windo syntax clear MarkWord" . i + " suggested by Marc Weber, use .* instead off ALL + exe "windo syntax match MarkWord" . i . " " . quoted_regexp . " containedin=.*" + endif + exe lastwinnr . "wincmd w" + if exists("*winrestview") + call winrestview(winview) + endif + 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:MW_CYCLE_MAX + exe "syntax clear MarkWord" . i + if g:mw_state >= 1 && g:MW_WORD{i} != "" + " quote regexp with / etc. e.g. pattern => /pattern/ + let quote = "/?~!@#$%^&*+-=,.:" + let j = 0 + while j < strlen(quote) + if stridx(g:MW_WORD{i}, quote[j]) < 0 + let quoted_regexp = quote[j] . g:MW_WORD{i} . quote[j] + break + endif + let j = j + 1 + endwhile + if j >= strlen(quote) + continue + endif + + let lastwinnr = winnr() + if exists("*winsaveview") + let winview = winsaveview() + endif + if exists("*matchadd") + windo silent! call matchdelete(3333 + i) + windo silent! call matchadd("MarkWord" . i, g:MW_WORD{i}, -10, 3333 + i) + else + exe "windo syntax clear MarkWord" . i + " suggested by Marc Weber, use .* instead off ALL + exe "windo syntax match MarkWord" . i . " " . quoted_regexp . " containedin=.*" + endif + exe lastwinnr . "wincmd w" + if exists("*winrestview") + call winrestview(winview) + endif + elseif g:MW_WORD{i} != "" + let lastwinnr = winnr() + if exists("*winsaveview") + let winview = winsaveview() + endif + if exists("*matchdelete") + windo silent! call matchdelete(3333 + i) + else + exe "windo syntax clear MarkWord" . i + endif + exe lastwinnr . "wincmd w" + if exists("*winrestview") + call winrestview(winview) + endif + endif + let i = i + 1 + endwhile +endfunction + +" return the mark string under the cursor +function! s:CurrentMark() + " define variables if they don't exist + call s:InitMarkVariables() + + let saved_line = line(".") + let saved_col = col(".") + let search_begin = saved_line>100?saved_line-100:1 + let search_end = saved_line+100= 1 && g:MW_WORD{i} != "" + call cursor(search_begin, 1) + let end_line = 0 + let end_col = 0 + while !(end_line > saved_line || end_line == saved_line && end_col >= saved_col) + let fwd = search(g:MW_WORD{i}, "eW", search_end) + if fwd == 0 || end_line == line(".") && end_col == col(".") + break + endif + let end_line = line(".") + let end_col = col(".") + endwhile + if !(end_line > saved_line || end_line == saved_line && end_col >= saved_col) + let i = i + 1 + continue + endif + call cursor(end_line, end_col) + let bwd = search(g:MW_WORD{i}, "cbW", search_begin) + if bwd == 0 + let i = i + 1 + continue + endif + let begin_line = line(".") + let begin_col = col(".") + if begin_line < saved_line || begin_line == saved_line && begin_col <= saved_col + let s:current_mark_position = begin_line . "_" . begin_col + let result = i + break + endif + endif + let i = i + 1 + endwhile + + call cursor(saved_line, saved_col) + if result > 0 + return g:MW_WORD{result} + endif + 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 exists("s:current_mark_position") && p == s:current_mark_position + call search(w, flags) + endif + let g:MW_LAST_SEARCHED = w + else + if g:MW_LAST_SEARCHED != "" + call search(g:MW_LAST_SEARCHED, flags) + else + call s:SearchAnyMark(flags) + let g:MW_LAST_SEARCHED = 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:MW_CYCLE_MAX + if g:mw_state >= 1 && g:MW_WORD{i} != "" + if w != "" + let w = w . '\|' . g:MW_WORD{i} + else + let w = g:MW_WORD{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 exists("s:current_mark_position") && p == s:current_mark_position + call search(w, flags) + endif + let g:MW_LAST_SEARCHED = "" +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:MW_LAST_SEARCHED != "" + 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