vim: add mark

This commit is contained in:
Mathieu Maret 2023-04-19 15:38:30 +02:00
parent 9885eebb12
commit 08eb96c70d
2 changed files with 638 additions and 457 deletions

View File

@ -1,457 +0,0 @@
" ScrollColors.vim - Colorsheme Scroller, Chooser, and Browser
"
" Author and maintainer: Yakov Lerner <iler_ml@fastmail.fm>
" 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 <F2> and <f3>, or \n and \p)
" and map them as follows:
" map <silent><F3> :NEXTCOLOR<cr>
" map <silent><F2> :PREVCOLOR<cr>
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 <silent><F3> :NEXTCOLOR<cr>
"map <silent><F2> :PREVCOLOR<cr>
"map <silent><F4> :SCROLLCOLOR<cr>
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 == "\<Left>" || key == "\<Up>" || c ==# 'h' || c ==# 'j'
call s:PrevSilent()
elseif key == "\<Down>" || key == "\<Right>" || 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=="\<C-L>"
redraw
elseif c == '#'
call s:JumpByIndex(list,total)
elseif key == "\<PageDown>"
call s:JumpByIndex2(list,total, (index-10>=1 ? index-10 : index-10+total))
elseif key == "\<PageUp>"
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<cr>
map \p :CP<cr>
map \c :echo g:colors_name<cr>
" 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)

638
.vim/plugin/mark.vim Normal file
View File

@ -0,0 +1,638 @@
" Script Name: mark.vim
" Version: 1.2.2 (global version)
" Last Change: January 30, 2019
" Author: Yuheng Xie <thinelephant@gmail.com>
" 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 <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(
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('<Plug>MarkSet', 'n')
nmap <unique> <silent> <leader>m <Plug>MarkSet
endif
if !hasmapto('<Plug>MarkSet', 'v')
vmap <unique> <silent> <leader>m <Plug>MarkSet
endif
if !hasmapto('<Plug>MarkRegex', 'n')
nmap <unique> <silent> <leader>r <Plug>MarkRegex
endif
if !hasmapto('<Plug>MarkRegex', 'v')
vmap <unique> <silent> <leader>r <Plug>MarkRegex
endif
if !hasmapto('<Plug>MarkClear', 'n')
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>
" 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 <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,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("<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 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<line("$")?saved_line+100:line("$")
let result = 0
let i = 1
while i <= g:MW_CYCLE_MAX
if g:mw_state >= 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