vim: add mark
This commit is contained in:
parent
9885eebb12
commit
08eb96c70d
@ -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
638
.vim/plugin/mark.vim
Normal 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
|
Loading…
Reference in New Issue
Block a user