From 1178b8be6d5eecd6be2cb0b3221e8cb19d3aafa1 Mon Sep 17 00:00:00 2001 From: gryf Date: Mon, 26 Mar 2012 19:05:47 +0200 Subject: [PATCH] Update of Mark, syntastic, taglisttoo and ctrlp plugins --- GetLatest/GetLatestVimScripts.dat | 2 +- bundle/git_ctrlp/autoload/ctrlp.vim | 182 +++- bundle/git_ctrlp/autoload/ctrlp/buffertag.vim | 30 +- bundle/git_ctrlp/autoload/ctrlp/changes.vim | 32 +- bundle/git_ctrlp/autoload/ctrlp/line.vim | 28 +- bundle/git_ctrlp/autoload/ctrlp/mrufiles.vim | 136 ++- bundle/git_ctrlp/autoload/ctrlp/undo.vim | 102 +- bundle/git_ctrlp/doc/ctrlp.txt | 112 +- bundle/git_ctrlp/plugin/ctrlp.vim | 14 + bundle/git_syntastic/plugin/syntastic.vim | 18 +- bundle/git_syntastic/syntax_checkers/go.vim | 2 +- .../syntax_checkers/javascript.vim | 2 +- bundle/git_syntastic/syntax_checkers/json.vim | 2 +- .../git_syntastic/syntax_checkers/puppet.vim | 51 +- .../git_syntastic/syntax_checkers/python.vim | 2 +- .../syntax_checkers/python/pylint.vim | 6 +- bundle/git_syntastic/syntax_checkers/vala.vim | 16 +- .../autoload/taglisttoo/lang/javascript.vim | 8 +- bundle/mark/autoload/mark.vim | 972 +++++++++++------- bundle/mark/doc/mark.txt | 269 +++-- bundle/mark/plugin/mark.vim | 127 ++- 21 files changed, 1335 insertions(+), 778 deletions(-) diff --git a/GetLatest/GetLatestVimScripts.dat b/GetLatest/GetLatestVimScripts.dat index 574f5c6..8c03480 100644 --- a/GetLatest/GetLatestVimScripts.dat +++ b/GetLatest/GetLatestVimScripts.dat @@ -7,7 +7,7 @@ ScriptID SourceID Filename 3304 17406 gundo.vim 2727 11120 jsbeautify.vim 2289 8922 loremipsum -2666 17554 Mark +2666 17661 Mark 1218 14455 nerdcommenter 2262 8944 occur.vim 2136 8206 repeat.vim diff --git a/bundle/git_ctrlp/autoload/ctrlp.vim b/bundle/git_ctrlp/autoload/ctrlp.vim index a186072..193e170 100644 --- a/bundle/git_ctrlp/autoload/ctrlp.vim +++ b/bundle/git_ctrlp/autoload/ctrlp.vim @@ -2,10 +2,10 @@ " File: autoload/ctrlp.vim " Description: Fuzzy file, buffer, mru and tag finder. " Author: Kien Nguyen -" Version: 1.7.2 +" Version: 1.7.4 " ============================================================================= -" Static variables {{{1 +" * Static variables {{{1 fu! s:opts() " Options let hst = exists('+hi') ? &hi : 20 @@ -21,6 +21,7 @@ fu! s:opts() \ 'g:ctrlp_highlight_match': ['s:mathi', [1, 'CtrlPMatch']], \ 'g:ctrlp_jump_to_buffer': ['s:jmptobuf', 2], \ 'g:ctrlp_lazy_update': ['s:lazy', 0], + \ 'g:ctrlp_match_func': ['s:matcher', {}], \ 'g:ctrlp_match_window_bottom': ['s:mwbottom', 1], \ 'g:ctrlp_match_window_reversed': ['s:mwreverse', 1], \ 'g:ctrlp_max_depth': ['s:maxdepth', 40], @@ -203,7 +204,7 @@ fu! s:Close() unl! s:focus s:hisidx s:hstgot s:marked s:statypes s:cline s:init s:savestr \ g:ctrlp_nolimit cal ctrlp#recordhist() - cal s:onexit() + cal s:extvar('exit') cal s:log(0) ec endf @@ -224,8 +225,10 @@ endf fu! ctrlp#reset() cal s:opts() + cal s:autocmds() cal ctrlp#utils#opts() cal ctrlp#mrufiles#opts() + cal s:extvar('opts') endf " * Files {{{1 fu! ctrlp#files() @@ -307,25 +310,28 @@ fu! s:lsCmd() retu cmd['types'][key][1] en endf -" Buffers {{{1 +" - Buffers {{{1 fu! ctrlp#buffers() retu map(filter(range(1, bufnr('$')), 'empty(getbufvar(v:val, "&bt"))' \ .' && getbufvar(v:val, "&bl") && strlen(bufname(v:val))'), \ 'fnamemodify(bufname(v:val), ":.")') endf " * MatchedItems() {{{1 -fu! s:MatchIt(items, pat, limit, mfunc, ipt) - let [newitems, crfile] = [[], exists('s:crfilerel') ? s:crfilerel : ''] - for item in a:items - try | if !( a:ipt && item == crfile ) && call(a:mfunc, [item, a:pat]) >= 0 +fu! s:MatchIt(items, pat, limit, mfunc, ipt, exc) + let [newitems, id, itlen] = [[], 0, len(a:items)] + wh id < itlen + let item = a:items[id] + let id += 1 + try | if !( a:ipt && item == a:exc ) && call(a:mfunc, [item, a:pat]) >= 0 cal add(newitems, item) en | cat | brea | endt if a:limit > 0 && len(newitems) >= a:limit | brea | en - endfo + endw + let s:mdata = [s:dyncwd, s:itemtype, s:regexp, a:items[(id):]] retu newitems endf -fu! s:MatchedItems(items, pat, limit, ipt) +fu! s:MatchedItems(items, str, pat, limit, ipt) let [type, mfunc] = [s:type(1), 'match'] if s:byfname && a:ipt let mfunc = 's:matchfname' @@ -333,11 +339,20 @@ fu! s:MatchedItems(items, pat, limit, ipt) let types = { 'tabs': 's:matchtabs', 'tabe': 's:matchtabe' } if has_key(types, type) | let mfunc = types[type] | en en - let newitems = s:MatchIt(a:items, a:pat, a:limit, mfunc, a:ipt) + let exc = exists('s:crfilerel') ? s:crfilerel : '' + let matfunc = 's:MatchIt' + let items = s:narrowable() ? s:matched + s:mdata[3] : a:items + let argms = [items, a:pat, a:limit, mfunc, a:ipt, exc] + if s:matcher != {} && has_key(s:matcher, 'match') + let [matfunc, argms[1], argms[3]] = s:matargs(mfunc, a:str) + let argms += [s:regexp] + en + let newitems = call(matfunc, argms) let s:matches = len(newitems) retu newitems endf -fu! s:SplitPattern(str) "{{{1 + +fu! s:SplitPattern(str) let str = a:str if s:migemo && s:regexp && len(str) > 0 && executable('cmigemo') let str = s:migemo(str) @@ -379,9 +394,8 @@ fu! s:Render(lines, pat, ipt) if s:dohighlight() | cal clearmatches() | en retu en - " Sort if not MRU - if ( s:itemtype != 2 && !exists('g:ctrlp_nolimit') ) - \ || s:prompt != ['', '', ''] + if ( ( s:itemtype != 2 && !exists('g:ctrlp_nolimit') ) + \ || s:prompt != ['', '', ''] ) && s:matcher == {} let s:compat = a:pat cal sort(lines, 's:mixedsort') unl s:compat @@ -412,7 +426,7 @@ fu! s:Update(str) if str == oldstr && !empty(str) && !exists('s:force') | retu | en let [pat, ipt] = [s:SplitPattern(str), s:ispathitem()] let lines = exists('g:ctrlp_nolimit') && empty(str) ? copy(g:ctrlp_lines) - \ : s:MatchedItems(g:ctrlp_lines, pat, s:winh, ipt) + \ : s:MatchedItems(g:ctrlp_lines, str, pat, s:winh, ipt) cal s:Render(lines, pat, ipt) endf @@ -459,8 +473,10 @@ endf fu! s:PrtAdd(char) unl! s:hstgot + let s:act_add = 1 let s:prompt[0] .= a:char cal s:BuildPrompt(1) + unl s:act_add endf fu! s:PrtBS() @@ -577,7 +593,7 @@ fu! s:PrtClearCache() cal ctrlp#clr(s:statypes[s:itemtype][1]) en if s:itemtype == 2 - let g:ctrlp_lines = ctrlp#mrufiles#list(-1, 1) + let g:ctrlp_lines = ctrlp#mrufiles#refresh() el cal ctrlp#setlines(s:itemtype) en @@ -588,13 +604,13 @@ endf fu! s:PrtDeleteMRU() if s:itemtype != 2 | retu | en - let [s:force, ags] = [1, [-1, 2]] + let [s:force, tbrem] = [1, []] if exists('s:marked') - let ags = [-1, 2, values(s:marked)] + let tbrem = values(s:marked) cal s:unmarksigns() unl s:marked en - let g:ctrlp_lines = call('ctrlp#mrufiles#list', ags) + let g:ctrlp_lines = ctrlp#mrufiles#remove(tbrem) cal s:BuildPrompt(1) unl s:force endf @@ -684,7 +700,7 @@ endf fu! s:ToggleType(dir) let ext = exists('g:ctrlp_ext_vars') ? len(g:ctrlp_ext_vars) : 0 - let s:itemtype = s:walker(g:ctrlp_builtins + ext, s:itemtype, a:dir) + let s:itemtype = s:walker(2 + ext, s:itemtype, a:dir) if s:byfname && !s:ispathitem() | let s:byfname = 0 | en unl! g:ctrlp_nolimit if has('syntax') && exists('g:syntax_on') @@ -699,8 +715,10 @@ fu! s:PrtSwitcher() cal s:BuildPrompt(1, s:Focus()) unl s:force endf -fu! s:SetWD(...) "{{{1 - let [pathmode, s:crfilerel] = [s:wpmode, fnamemodify(s:crfile, ':.')] +" - SetWD() {{{1 +fu! s:SetWD(...) + let pathmode = s:wpmode + let [s:crfilerel, s:dyncwd] = [fnamemodify(s:crfile, ':.'), getcwd()] if a:0 && strlen(a:1) | if type(a:1) cal ctrlp#setdir(a:1) | retu el @@ -717,7 +735,7 @@ fu! s:SetWD(...) "{{{1 cal extend(markers, s:rmarkers, 0) en for marker in markers - cal s:findroot(getcwd(), marker, 0, 0) + cal s:findroot(s:dyncwd, marker, 0, 0) if exists('s:foundroot') | brea | en endfo unl! s:foundroot @@ -742,7 +760,7 @@ fu! ctrlp#acceptfile(mode, line, ...) if j2l | cal ctrlp#j2l(j2l) | en el " Determine the command to use - let useb = bufnr > 0 && empty(tail) + let useb = bufnr > 0 && getbufvar(bufnr, '&bl') && empty(tail) let cmd = \ md == 't' || s:splitwin == 1 ? ( useb ? 'tab sb' : 'tabe' ) : \ md == 'h' || s:splitwin == 2 ? ( useb ? 'sb' : 'new' ) : @@ -794,10 +812,11 @@ fu! s:AcceptSelection(mode) if empty(line) | retu | en " Do something with it let actfunc = s:itemtype < 3 ? 'ctrlp#acceptfile' - \ : g:ctrlp_ext_vars[s:itemtype - ( g:ctrlp_builtins + 1 )]['accept'] + \ : g:ctrlp_ext_vars[s:itemtype - 3]['accept'] cal call(actfunc, [a:mode, line]) endf -fu! s:CreateNewFile(...) "{{{1 +" - CreateNewFile() {{{1 +fu! s:CreateNewFile(...) let [md, str] = ['', join(s:prompt, '')] if empty(str) | retu | en if s:argmap && !a:0 @@ -830,8 +849,7 @@ fu! s:CreateNewFile(...) "{{{1 endf " * OpenMulti() {{{1 fu! s:MarkToOpen() - if s:bufnr <= 0 || s:opmul == '0' - \ || ( s:itemtype > g:ctrlp_builtins && s:type() !~ 'rts' ) + if s:bufnr <= 0 || s:opmul == '0' || ( s:itemtype > 2 && s:type() !~ 'rts' ) retu en let line = !empty(s:matched) ? s:matched[line('.') - 1] : '' @@ -875,7 +893,8 @@ fu! s:OpenMulti() " Move the cursor to a reusable window let [tail, fnesc] = [s:tail(), exists('*fnameescape') && v:version > 701] let [emptytail, nwpt] = [empty(tail), exists('g:ctrlp_open_multiple_files')] - let useb = bufnr('^'.mkd[0].'$') > 0 && emptytail + let bufnr = bufnr('^'.mkd[0].'$') + let useb = bufnr > 0 && getbufvar(bufnr, '&bl') && emptytail let fst = call('ctrlp#normcmd', useb ? ['b', 'bo vert sb'] : ['e']) " Check if it's a replaceable buffer let repabl = ( empty(bufname('%')) && empty(&l:ft) ) || s:nosplit() @@ -886,7 +905,7 @@ fu! s:OpenMulti() " Open the files for va in mkd let bufnr = bufnr('^'.va.'$') - let useb = bufnr > 0 && emptytail + let useb = bufnr > 0 && getbufvar(bufnr, '&bl') && emptytail let snd = md != '' && has_key(cmds, md) ? \ ( useb ? cmds[md][0] : cmds[md][1] ) : ( useb ? 'vert sb' : 'vne' ) let cmd = ic == 1 && ( ucr == 'r' || repabl ) ? fst : snd @@ -925,6 +944,15 @@ fu! s:comptime(s1, s2) retu time1 == time2 ? 0 : time1 < time2 ? 1 : -1 endf +fu! s:compmre(...) + " By last entered time (buffer only) + if !exists('s:mrbs') + let s:mrbs = ctrlp#mrufiles#bufs() + en + let cwd = getcwd() + retu index(s:mrbs, cwd.s:lash().a:1) - index(s:mrbs, cwd.s:lash().a:2) +endf + fu! s:comparent(s1, s2) " By same parent dir let cwd = getcwd() @@ -968,8 +996,11 @@ fu! s:mixedsort(s1, s2) if s:itemtype < 3 && s:height < 51 let [par, cfn] = [s:comparent(a:s1, a:s2), s:compfnlen(a:s1, a:s2)] if s:height < 21 - let ctm = s:comptime(a:s1, a:s2) - retu 12 * cml + 6 * par + 3 * cfn + 2 * ctm + cln + let [muls, ctm] = s:itemtype == 1 + \ ? [[6, 3, 2, 12], s:compmre(a:s1, a:s2)] + \ : [[12, 6, 3, 2], s:comptime(a:s1, a:s2)] + unl! s:mrbs + retu muls[0] * cml + muls[1] * par + muls[2] * cfn + muls[3] * ctm + cln en retu 6 * cml + 3 * par + 2 * cfn + cln en @@ -1001,7 +1032,7 @@ fu! ctrlp#statusline() let byfname = s:byfname ? 'file' : 'path' let marked = s:opmul != '0' ? \ exists('s:marked') ? ' <'.s:dismrk().'>' : ' <->' : '' - if has_key(s:status, 'main') + if s:status != {} && has_key(s:status, 'main') let args = [focus, byfname, s:regexp, prv, item, nxt, marked] let &l:stl = call(s:status['main'], args) el @@ -1022,7 +1053,8 @@ endf fu! ctrlp#progress(enum) if has('macunix') || has('mac') | sl 1m | en - let &l:stl = has_key(s:status, 'prog') ? call(s:status['prog'], [a:enum]) + let &l:stl = s:status != {} && has_key(s:status, 'prog') + \ ? call(s:status['prog'], [a:enum]) \ : '%#CtrlPStats# '.a:enum.' %* %=%<%#CtrlPMode2# '.getcwd().' %*' redraws endf @@ -1065,9 +1097,8 @@ fu! s:lash(...) endf fu! s:ispathitem() - let ext = s:itemtype - ( g:ctrlp_builtins + 1 ) - retu s:itemtype < 3 - \ || ( s:itemtype > 2 && g:ctrlp_ext_vars[ext]['type'] == 'path' ) + retu s:itemtype < 3 || + \ ( s:itemtype > 2 && g:ctrlp_ext_vars[s:itemtype - 3]['type'] == 'path' ) endf fu! ctrlp#dirnfile(entries) @@ -1156,7 +1187,7 @@ endf fu! ctrlp#setdir(path, ...) let cmd = a:0 ? a:1 : 'lc!' sil! exe cmd ctrlp#fnesc(a:path) - let s:crfilerel = fnamemodify(s:crfile, ':.') + let [s:crfilerel, s:dyncwd] = [fnamemodify(s:crfile, ':.'), getcwd()] endf fu! ctrlp#setlcdir() @@ -1180,6 +1211,7 @@ fu! ctrlp#syntax() endf fu! s:highlight(pat, grp, ipt) + if s:matcher != {} | retu | en cal clearmatches() if !empty(a:pat) && a:ipt let pat = s:regexp ? substitute(a:pat, '\\\@ \\zs', 'g') : a:pat @@ -1342,6 +1374,22 @@ fu! s:argmaps(md, ...) retu a:md endf " Misc {{{2 +fu! s:narrowable() + retu exists('s:act_add') && exists('s:matched') && s:matched != [] + \ && exists('s:mdata') && s:mdata[:2] == [s:dyncwd, s:itemtype, s:regexp] + \ && s:matcher == {} +endf + +fu! s:matargs(mfunc, str) + let match_type = { + \ 'match': 'full-line', + \ 's:matchfname': 'filename-only', + \ 's:matchtabs': 'first-non-tab', + \ 's:matchtabe': 'until-last-tab', + \ } + retu [s:matcher['match'], a:str, match_type[a:mfunc]] +endf + fu! s:log(m) if exists('g:ctrlp_log') && g:ctrlp_log | if a:m let cadir = ctrlp#utils#cachedir() @@ -1365,9 +1413,8 @@ fu! s:getenv() let s:wpmode = exists('b:ctrlp_working_path_mode') \ ? b:ctrlp_working_path_mode : s:pathmode if exists('g:ctrlp_extensions') - if index(g:ctrlp_extensions, 'undo') >= 0 && exists('*undotree') - \ && ( v:version > 703 || ( v:version == 703 && has('patch005') ) ) - let s:undotree = undotree() + if index(g:ctrlp_extensions, 'undo') >= 0 + let s:undos = s:getundo() en if index(g:ctrlp_extensions, 'tag') >= 0 let s:tagfiles = s:tagfiles() @@ -1440,8 +1487,8 @@ fu! s:regexfilter(str) retu str endf -fu! s:walker(max, pos, dir) - retu a:dir > 0 ? a:pos < a:max ? a:pos + 1 : 0 : a:pos > 0 ? a:pos - 1 : a:max +fu! s:walker(m, p, d) + retu a:d > 0 ? a:p < a:m ? a:p + a:d : 0 : a:p > 0 ? a:p + a:d : a:m endf fu! s:matchfname(item, pat) @@ -1478,18 +1525,30 @@ fu! s:insertcache(str) endf " Extensions {{{2 fu! s:type(...) - let ext = s:itemtype - ( g:ctrlp_builtins + 1 ) - retu s:itemtype > 2 ? g:ctrlp_ext_vars[ext][a:0 ? 'type' : 'sname'] : s:itemtype + retu s:itemtype > 2 + \ ? g:ctrlp_ext_vars[s:itemtype - 3][a:0 ? 'type' : 'sname'] : s:itemtype endf fu! s:tagfiles() retu filter(map(tagfiles(), 'fnamemodify(v:val, ":p")'), 'filereadable(v:val)') endf -fu! s:onexit() +fu! s:extvar(key) if exists('g:ctrlp_ext_vars') cal map(filter(copy(g:ctrlp_ext_vars), - \ 'has_key(v:val, "exit")'), 'eval(v:val["exit"])') + \ 'has_key(v:val, a:key)'), 'eval(v:val[a:key])') + en +endf + +fu! s:getundo() + if exists('*undotree') + \ && ( v:version > 703 || ( v:version == 703 && has('patch005') ) ) + retu [1, undotree()] + el + redi => result + sil! undol + redi END + retu [0, split(result, "\n")[1:]] en endf @@ -1500,6 +1559,10 @@ endf fu! ctrlp#prtclear() cal s:PrtClear() endf + +fu! ctrlp#switchtype(id) + cal s:ToggleType(a:id - s:itemtype) +endf "}}}1 " * Initialization {{{1 fu! ctrlp#setlines(type) @@ -1507,7 +1570,7 @@ fu! ctrlp#setlines(type) let types = [ \ 'ctrlp#files()', \ 'ctrlp#buffers()', - \ 'ctrlp#mrufiles#list(-1)', + \ 'ctrlp#mrufiles#list()', \ ] if exists('g:ctrlp_ext_vars') cal map(copy(g:ctrlp_ext_vars), 'add(types, v:val["init"])') @@ -1527,16 +1590,27 @@ fu! ctrlp#init(type, ...) cal ctrlp#setlines(a:type) cal s:BuildPrompt(1) endf -if has('autocmd') "{{{1 +" - Autocmds {{{1 +fu! s:autocmds() + if !has('autocmd') | retu | en aug CtrlPAug au! au BufEnter ControlP cal s:checkbuf() au BufLeave ControlP cal s:Close() au VimLeavePre * cal s:leavepre() - if s:lazy - au CursorHold ControlP cal s:ForceUpdate() - en aug END -en "}}} + if exists('#CtrlPLazy') + au! CtrlPLazy + en + if s:lazy + aug CtrlPLazy + au! + au CursorHold ControlP cal s:ForceUpdate() + aug END + en +endf + +cal s:autocmds() +"}}} " vim:fen:fdm=marker:fmr={{{,}}}:fdl=0:fdc=1:ts=2:sw=2:sts=2 diff --git a/bundle/git_ctrlp/autoload/ctrlp/buffertag.vim b/bundle/git_ctrlp/autoload/ctrlp/buffertag.vim index 345f876..68c131d 100644 --- a/bundle/git_ctrlp/autoload/ctrlp/buffertag.vim +++ b/bundle/git_ctrlp/autoload/ctrlp/buffertag.vim @@ -20,6 +20,7 @@ let s:buftag_var = { \ 'sname': 'bft', \ 'exit': 'ctrlp#buffertag#exit()', \ 'type': 'tabs', + \ 'opts': 'ctrlp#buffertag#opts()', \ } let g:ctrlp_ext_vars = exists('g:ctrlp_ext_vars') && !empty(g:ctrlp_ext_vars) @@ -27,7 +28,7 @@ let g:ctrlp_ext_vars = exists('g:ctrlp_ext_vars') && !empty(g:ctrlp_ext_vars) let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars) -fu! s:opts() +fu! ctrlp#buffertag#opts() let opts = { \ 'g:ctrlp_buftag_systemenc': ['s:enc', &enc], \ 'g:ctrlp_buftag_ctags_bin': ['s:bin', ''], @@ -37,7 +38,7 @@ fu! s:opts() exe 'let' va[0] '=' string(exists(ke) ? eval(ke) : va[1]) endfo endf -cal s:opts() +cal ctrlp#buffertag#opts() fu! s:bins() let bins = [ @@ -196,6 +197,21 @@ fu! s:parseline(line) let [bufnr, bufname] = [bufnr('^'.vals[2].'$'), fnamemodify(vals[2], ':p:t')] retu vals[1].' '.vals[4].'|'.bufnr.':'.bufname.'|'.vals[6].'| '.vals[3] endf + +fu! s:syntax() + if !hlexists('CtrlPTagKind') + hi link CtrlPTagKind Title + en + if !hlexists('CtrlPBufName') + hi link CtrlPBufName Directory + en + if !hlexists('CtrlPTabExtra') + hi link CtrlPTabExtra Comment + en + sy match CtrlPTagKind '\zs[^\t|]\+\ze|\d\+:[^|]\+|\d\+|' + sy match CtrlPBufName '|\d\+:\zs[^|]\+\ze|\d\+|' + sy match CtrlPTabExtra '\zs\t.*\ze$' contains=CtrlPBufName,CtrlPTagKind +endf " Public {{{1 fu! ctrlp#buffertag#init(fname) let bufs = exists('s:btmode') && s:btmode @@ -203,14 +219,12 @@ fu! ctrlp#buffertag#init(fname) \ : [exists('s:bufname') ? s:bufname : a:fname] let lines = [] for each in bufs - let tftype = get(split(getbufvar(each, '&ft'), '\.'), 0, '') - cal extend(lines, s:process(each, tftype)) + let bname = fnamemodify(each, ':p') + let tftype = get(split(getbufvar(bname, '&ft'), '\.'), 0, '') + cal extend(lines, s:process(bname, tftype)) endfo if has('syntax') && exists('g:syntax_on') - if !hlexists('CtrlPTabExtra') - hi link CtrlPTabExtra Comment - en - sy match CtrlPTabExtra '\zs\t.*\ze$' + cal s:syntax() en retu lines endf diff --git a/bundle/git_ctrlp/autoload/ctrlp/changes.vim b/bundle/git_ctrlp/autoload/ctrlp/changes.vim index 4fe5f68..e534ed8 100644 --- a/bundle/git_ctrlp/autoload/ctrlp/changes.vim +++ b/bundle/git_ctrlp/autoload/ctrlp/changes.vim @@ -1,20 +1,9 @@ " ============================================================================= " File: autoload/ctrlp/changes.vim -" Description: Change list extension - Jump to a recent change in any buffer +" Description: Change list extension " Author: Kien Nguyen " ============================================================================= -" User Configuration {{{1 -" Enable: -" let g:ctrlp_extensions += ['changes'] -" Create Some Commands: -" " Single buffer -" com! -n=? -com=buffer CtrlPChange -" \ cal ctrlp#init(ctrlp#changes#cmd(0, )) -" " All listed buffers -" com! CtrlPChangeAll cal ctrlp#init(ctrlp#changes#cmd(1)) -"}}} - " Init {{{1 if exists('g:loaded_ctrlp_changes') && g:loaded_ctrlp_changes fini @@ -54,6 +43,17 @@ fu! s:process(clines, ...) endfo retu reverse(filter(clines, 'count(clines, v:val) == 1')) endf + +fu! s:syntax() + if !hlexists('CtrlPBufName') + hi link CtrlPBufName Directory + en + if !hlexists('CtrlPTabExtra') + hi link CtrlPTabExtra Comment + en + sy match CtrlPBufName '\t|\d\+:\zs[^|]\+\ze|\d\+:\d\+|$' + sy match CtrlPTabExtra '\zs\t.*\ze$' contains=CtrlPBufName +endf " Public {{{1 fu! ctrlp#changes#init(original_bufnr, fname) let fname = exists('s:bufname') ? s:bufname : a:fname @@ -62,7 +62,8 @@ fu! ctrlp#changes#init(original_bufnr, fname) let [swb, &swb] = [&swb, ''] let lines = [] for each in bufs - let [bufnr, fnamet] = [bufnr('^'.each.'$'), fnamemodify(each, ':t')] + let [bname, fnamet] = [fnamemodify(each, ':p'), fnamemodify(each, ':t')] + let bufnr = bufnr('^'.bname.'$') if bufnr > 0 cal extend(lines, s:process(s:changelist(bufnr), bufnr, fnamet)) en @@ -72,10 +73,7 @@ fu! ctrlp#changes#init(original_bufnr, fname) let g:ctrlp_nolimit = 1 if has('syntax') && exists('g:syntax_on') cal ctrlp#syntax() - if !hlexists('CtrlPTabExtra') - hi link CtrlPTabExtra Comment - en - sy match CtrlPTabExtra '\zs\t.*\ze$' + cal s:syntax() en retu lines endf diff --git a/bundle/git_ctrlp/autoload/ctrlp/line.vim b/bundle/git_ctrlp/autoload/ctrlp/line.vim index 961ede4..28b81d6 100644 --- a/bundle/git_ctrlp/autoload/ctrlp/line.vim +++ b/bundle/git_ctrlp/autoload/ctrlp/line.vim @@ -1,16 +1,9 @@ " ============================================================================= " File: autoload/ctrlp/line.vim -" Description: Line extension - Find a line in any buffer +" Description: Line extension " Author: Kien Nguyen " ============================================================================= -" User Configuration {{{1 -" Enable: -" let g:ctrlp_extensions += ['line'] -" Create A Command: -" com! CtrlPLine cal ctrlp#init(ctrlp#line#id()) -"}}} - " Init {{{1 if exists('g:loaded_ctrlp_line') && g:loaded_ctrlp_line fini @@ -29,13 +22,25 @@ let g:ctrlp_ext_vars = exists('g:ctrlp_ext_vars') && !empty(g:ctrlp_ext_vars) \ ? add(g:ctrlp_ext_vars, s:line_var) : [s:line_var] let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars) +" Utilities {{{1 +fu! s:syntax() + if !hlexists('CtrlPBufName') + hi link CtrlPBufName Directory + en + if !hlexists('CtrlPTabExtra') + hi link CtrlPTabExtra Comment + en + sy match CtrlPBufName '\t|\zs[^|]\+\ze|\d\+:\d\+|$' + sy match CtrlPTabExtra '\zs\t.*\ze$' contains=CtrlPBufName +endf " Public {{{1 fu! ctrlp#line#init() let [bufs, lines] = [filter(ctrlp#buffers(), 'filereadable(v:val)'), []] for each in bufs let [fnamet, from_file] = [fnamemodify(each, ':t'), readfile(each)] + let bname = fnamemodify(each, ':p') cal map(from_file, 'tr(v:val, '' '', '' '')') - let [id, len_ff, bufnr] = [1, len(from_file), bufnr('^'.each.'$')] + let [id, len_ff, bufnr] = [1, len(from_file), bufnr('^'.bname.'$')] wh id <= len_ff let from_file[id-1] .= ' |'.fnamet.'|'.bufnr.':'.id.'|' let id += 1 @@ -44,10 +49,7 @@ fu! ctrlp#line#init() cal extend(lines, from_file) endfo if has('syntax') && exists('g:syntax_on') - if !hlexists('CtrlPTabExtra') - hi link CtrlPTabExtra Comment - en - sy match CtrlPTabExtra '\zs\t.*\ze$' + cal s:syntax() en retu lines endf diff --git a/bundle/git_ctrlp/autoload/ctrlp/mrufiles.vim b/bundle/git_ctrlp/autoload/ctrlp/mrufiles.vim index ff485e7..f8c3048 100644 --- a/bundle/git_ctrlp/autoload/ctrlp/mrufiles.vim +++ b/bundle/git_ctrlp/autoload/ctrlp/mrufiles.vim @@ -17,76 +17,108 @@ fu! ctrlp#mrufiles#opts() for [ke, va] in items(opts) exe 'let' va[0] '=' string(exists(ke) ? eval(ke) : va[1]) endfo - let s:csen = s:csen ? '#' : '?' + let [s:csen, s:mrbs] = [s:csen ? '#' : '?', []] + if exists('s:locked') + cal ctrlp#mrufiles#init() + en endf cal ctrlp#mrufiles#opts() -fu! ctrlp#mrufiles#list(bufnr, ...) "{{{1 - if s:locked | retu | en - let bufnr = a:bufnr + 0 - if bufnr > 0 - let fn = fnamemodify(bufname(bufnr), ':p') - let fn = exists('+ssl') ? tr(fn, '/', '\') : fn - if empty(fn) || !empty(&bt) || ( !empty(s:in) && fn !~# s:in ) - \ || ( !empty(s:ex) && fn =~# s:ex ) || !filereadable(fn) - retu - en - en +" Utilities {{{1 +fu! s:excl(fn) + retu !empty(s:ex) && a:fn =~# s:ex +endf + +fu! s:readcache() if !exists('s:cadir') || !exists('s:cafile') let s:cadir = ctrlp#utils#cachedir().ctrlp#utils#lash().'mru' let s:cafile = s:cadir.ctrlp#utils#lash().'cache.txt' en - if a:0 && a:1 == 2 - let mrufs = [] - if a:0 == 2 - let mrufs = ctrlp#utils#readfile(s:cafile) - cal filter(mrufs, 'index(a:2, v:val) < 0') - en - cal ctrlp#utils#writecache(mrufs, s:cadir, s:cafile) - retu map(mrufs, 'fnamemodify(v:val, '':.'')') + retu ctrlp#utils#readfile(s:cafile) +endf + +fu! s:reformat(mrufs) + if s:re + let cwd = exists('+ssl') ? tr(getcwd(), '/', '\') : getcwd() + cal filter(a:mrufs, '!stridx(v:val, cwd)') en - " Get the list - let mrufs = ctrlp#utils#readfile(s:cafile) - " Remove non-existent files - if a:0 && a:1 == 1 - cal filter(mrufs, '!empty(ctrlp#utils#glob(v:val, 1)) && !s:excl(v:val)') - if exists('+ssl') - cal map(mrufs, 'tr(v:val, ''/'', ''\'')') - cal filter(mrufs, 'count(mrufs, v:val) == 1') - en - cal ctrlp#utils#writecache(mrufs, s:cadir, s:cafile) + retu map(a:mrufs, 'fnamemodify(v:val, '':.'')') +endf + +fu! s:record(bufnr, ...) + if s:locked | retu | en + let bufnr = a:bufnr + 0 + if bufnr <= 0 | retu | en + let fn = fnamemodify(bufname(bufnr), ':p') + let fn = exists('+ssl') ? tr(fn, '/', '\') : fn + cal filter(s:mrbs, 'v:val !='.s:csen.' fn') + cal insert(s:mrbs, fn) + if empty(fn) || !empty(&bt) || ( !empty(s:in) && fn !~# s:in ) + \ || ( !empty(s:ex) && fn =~# s:ex ) || !filereadable(fn) + \ || ( a:0 && a:1 == 1 ) + retu en - " Return the list with the active buffer removed - if bufnr == -1 - if s:re - let cwd = exists('+ssl') ? tr(getcwd(), '/', '\') : getcwd() - cal filter(mrufs, '!stridx(v:val, cwd)') - en - retu map(mrufs, 'fnamemodify(v:val, '':.'')') - en - " Remove old entry + let mrufs = s:readcache() cal filter(mrufs, 'v:val !='.s:csen.' fn') - " Insert new one cal insert(mrufs, fn) - " Remove oldest entry or entries if len(mrufs) > s:max | cal remove(mrufs, s:max, -1) | en cal ctrlp#utils#writecache(mrufs, s:cadir, s:cafile) -endf "}}} -fu! s:excl(fn) "{{{ - retu !empty(s:ex) && a:fn =~# s:ex -endf "}}} -fu! ctrlp#mrufiles#init() "{{{1 +endf +" Public {{{1 +fu! ctrlp#mrufiles#refresh() + let mrufs = s:readcache() + cal filter(mrufs, '!empty(ctrlp#utils#glob(v:val, 1)) && !s:excl(v:val)') + if exists('+ssl') + cal map(mrufs, 'tr(v:val, ''/'', ''\'')') + cal filter(mrufs, 'count(mrufs, v:val) == 1') + en + cal ctrlp#utils#writecache(mrufs, s:cadir, s:cafile) + retu s:reformat(mrufs) +endf + +fu! ctrlp#mrufiles#remove(files) + let mrufs = [] + if a:files != [] + let mrufs = s:readcache() + cal filter(mrufs, 'index(a:files, v:val) < 0') + en + cal ctrlp#utils#writecache(mrufs, s:cadir, s:cafile) + retu map(mrufs, 'fnamemodify(v:val, '':.'')') +endf + +fu! ctrlp#mrufiles#list(...) + if a:0 | cal s:record(a:1) | retu | en + retu s:reformat(s:readcache()) +endf + +fu! ctrlp#mrufiles#bufs() + retu s:mrbs +endf + +fu! ctrlp#mrufiles#init() + if !has('autocmd') | retu | en let s:locked = 0 aug CtrlPMRUF au! - au BufReadPost,BufNewFile,BufWritePost * - \ cal ctrlp#mrufiles#list(expand('', 1)) - if s:mre - au BufEnter,BufUnload * - \ cal ctrlp#mrufiles#list(expand('', 1)) - en + au BufReadPost,BufNewFile,BufWritePost * cal s:record(expand('', 1)) au QuickFixCmdPre *vimgrep* let s:locked = 1 au QuickFixCmdPost *vimgrep* let s:locked = 0 aug END + aug CtrlPMREB + au! + au BufEnter,BufUnload * cal s:record(expand('', 1), 1) + aug END + if exists('#CtrlPMREF') + au! CtrlPMREF + en + if s:mre + aug CtrlPMREF + au! + au BufEnter,BufUnload * cal s:record(expand('', 1)) + aug END + if exists('#CtrlPMREB') + au! CtrlPMREB + en + en endf "}}} diff --git a/bundle/git_ctrlp/autoload/ctrlp/undo.vim b/bundle/git_ctrlp/autoload/ctrlp/undo.vim index 9b371d8..889f663 100644 --- a/bundle/git_ctrlp/autoload/ctrlp/undo.vim +++ b/bundle/git_ctrlp/autoload/ctrlp/undo.vim @@ -1,28 +1,21 @@ " ============================================================================= " File: autoload/ctrlp/undo.vim -" Description: Undo extension - Browse undo history (requires Vim 7.3.005+) +" Description: Undo extension " Author: Kien Nguyen " ============================================================================= -" User Configuration {{{1 -" Enable: -" let g:ctrlp_extensions += ['undo'] -" Create A Command: -" com! CtrlPUndo cal ctrlp#init(ctrlp#undo#id()) -"}}} - " Init {{{1 if ( exists('g:loaded_ctrlp_undo') && g:loaded_ctrlp_undo ) - \ || !( v:version > 703 || ( v:version == 703 && has('patch005') ) ) fini en let g:loaded_ctrlp_undo = 1 let s:undo_var = { - \ 'init': 'ctrlp#undo#init(s:undotree)', + \ 'init': 'ctrlp#undo#init(s:undos)', \ 'accept': 'ctrlp#undo#accept', \ 'lname': 'undo', \ 'sname': 'udo', + \ 'exit': 'ctrlp#undo#exit()', \ 'type': 'line', \ } @@ -30,36 +23,31 @@ let g:ctrlp_ext_vars = exists('g:ctrlp_ext_vars') && !empty(g:ctrlp_ext_vars) \ ? add(g:ctrlp_ext_vars, s:undo_var) : [s:undo_var] let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars) + +let s:text = map(['second', 'seconds', 'minutes', 'hours', 'days', 'weeks', + \ 'months', 'years'], '" ".v:val." ago"') " Utilities {{{1 -fu! s:flatten(tree) +fu! s:flatten(tree, cur) let flatdict = {} for each in a:tree - cal extend(flatdict, { each['seq'] : each['time'] }) + let saved = has_key(each, 'save') ? 'saved' : '' + let current = each['seq'] == a:cur ? 'current' : '' + cal extend(flatdict, { each['seq'] : [each['time'], saved, current] }) if has_key(each, 'alt') - cal extend(flatdict, s:flatten(each['alt'])) + cal extend(flatdict, s:flatten(each['alt'], a:cur)) en endfo retu flatdict endf -fu! s:humantime(nr) - let elapsed = localtime() - a:nr - let mins = elapsed / 60 - let hrs = elapsed / 3600 - let days = elapsed / 86400 - let wks = elapsed / 604800 - let mons = elapsed / 2592000 - let yrs = elapsed / 31536000 - let text = [ - \ ' second ago', - \ ' seconds ago', - \ ' minutes ago', - \ ' hours ago', - \ ' days ago', - \ ' weeks ago', - \ ' months ago', - \ ' years ago', - \ ] +fu! s:elapsed(nr) + let [text, time] = [s:text, localtime() - a:nr] + let mins = time / 60 + let hrs = time / 3600 + let days = time / 86400 + let wks = time / 604800 + let mons = time / 2592000 + let yrs = time / 31536000 if yrs > 1 retu yrs.text[7] elsei mons > 1 @@ -72,42 +60,66 @@ fu! s:humantime(nr) retu hrs.text[3] elsei mins > 1 retu mins.text[2] - elsei elapsed == 1 - retu elapsed.text[0] - elsei elapsed < 120 - retu elapsed.text[1] + elsei time == 1 + retu time.text[0] + elsei time < 120 + retu time.text[1] en endf fu! s:syntax() - for [ke, va] in items({'T': 'Directory', 'Br': 'Comment', 'Nr': 'String'}) + for [ke, va] in items({'T': 'Directory', 'Br': 'Comment', 'Nr': 'String', + \ 'Sv': 'Comment', 'Po': 'Title'}) if !hlexists('CtrlPUndo'.ke) exe 'hi link CtrlPUndo'.ke va en endfo - sy match CtrlPUndoT '\d\+ \zs[^ ]\+\ze' + sy match CtrlPUndoT '\v\d+ \zs[^ ]+\ze|\d+:\d+:\d+' sy match CtrlPUndoBr '\[\|\]' - sy match CtrlPUndoNr '\[\d\+\]$' contains=CtrlPUndoBr + sy match CtrlPUndoNr '\[\d\+\]' contains=CtrlPUndoBr + sy match CtrlPUndoSv 'saved' + sy match CtrlPUndoPo 'current' endf fu! s:dict2list(dict) - let dict = map(a:dict, 's:humantime(v:val)') - retu map(keys(dict), 'eval(''[v:val, dict[v:val]]'')') + for ke in keys(a:dict) + let a:dict[ke][0] = s:elapsed(a:dict[ke][0]) + endfo + retu map(keys(a:dict), 'eval(''[v:val, a:dict[v:val]]'')') endf fu! s:compval(...) retu a:2[0] - a:1[0] endf + +fu! s:format(...) + let saved = !empty(a:1[1][1]) ? ' '.a:1[1][1] : '' + let current = !empty(a:1[1][2]) ? ' '.a:1[1][2] : '' + retu a:1[1][0].' ['.a:1[0].']'.saved.current +endf + +fu! s:formatul(...) + let parts = matchlist(a:1, + \ '\v^\s+(\d+)\s+\d+\s+([^ ]+\s?[^ ]+|\d+\s\w+\s\w+)(\s*\d*)$') + retu parts[2].' ['.parts[1].']'.( parts[3] != '' ? ' saved' : '' ) +endf " Public {{{1 fu! ctrlp#undo#init(undo) - let entries = a:undo['entries'] + let entries = a:undo[0] ? a:undo[1]['entries'] : a:undo[1] if empty(entries) | retu [] | en if has('syntax') && exists('g:syntax_on') cal s:syntax() en let g:ctrlp_nolimit = 1 - let entries = sort(s:dict2list(s:flatten(entries)), 's:compval') - retu map(entries, 'v:val[1]." [".v:val[0]."]"') + if !exists('s:lines') + if a:undo[0] + let entries = s:dict2list(s:flatten(entries, a:undo[1]['seq_cur'])) + let s:lines = map(sort(entries, 's:compval'), 's:format(v:val)') + el + let s:lines = map(reverse(entries), 's:formatul(v:val)') + en + en + retu s:lines endf fu! ctrlp#undo#accept(mode, str) @@ -120,6 +132,10 @@ endf fu! ctrlp#undo#id() retu s:id endf + +fu! ctrlp#undo#exit() + unl! s:lines +endf "}}} " vim:fen:fdm=marker:fmr={{{,}}}:fdl=0:fdc=1:ts=2:sw=2:sts=2 diff --git a/bundle/git_ctrlp/doc/ctrlp.txt b/bundle/git_ctrlp/doc/ctrlp.txt index a63f461..444d658 100644 --- a/bundle/git_ctrlp/doc/ctrlp.txt +++ b/bundle/git_ctrlp/doc/ctrlp.txt @@ -1,4 +1,4 @@ -*ctrlp.txt* Fuzzy file, buffer, mru and tag finder. v1.7.2 +*ctrlp.txt* Fuzzy file, buffer, mru and tag finder. v1.7.4 *CtrlP* *ControlP* *'ctrlp'* *'ctrl-p'* =============================================================================== # # @@ -175,12 +175,10 @@ only need to keep the lines that you’ve changed the values (inside []): > \ } < Note: In some terminals, it’s not possible to remap without also changing - (|key-codes|). So if pressing moves the cursor to the left instead of -deleting a char for you, add this to your |vimrc| to disable the default -mapping: > - let g:ctrlp_prompt_mappings = { - \ 'PrtCurLeft()': ['', ''] - \ } + (|keycodes|). So if pressing moves the cursor to the left instead of +deleting a char for you, add this to your |.vimrc| to disable the plugin’s +default mapping: > + let g:ctrlp_prompt_mappings = { 'PrtCurLeft()': ['', ''] } < *'g:ctrlp_mruf_max'* @@ -386,8 +384,73 @@ Example: > \ 'prog': 'Function_Name_2', \ } < +Structure of the functions: > + function! Function_Name_1(focus, byfname, regex, prev, item, next, marked) + " Arguments: + " | + " +- a:focus : The focus of the prompt: "prt" or "win". + " | + " +- a:byfname : In filename mode or in full path mode: "file" or "path". + " | + " +- a:regex : In regex mode: 1 or 0. + " | + " +- a:prev : The previous search mode. + " | + " +- a:item : The current search mode. + " | + " +- a:next : The next search mode. + " | + " +- a:marked : The number of marked files, or a comma separated list of + " the filenames. + + return full_statusline + endfunction + + function! Function_Name_2(str) + " a:str : Either the number of files scanned so far, or a string indicating + " the current directory is being scanned with a user_command. + + return full_statusline + endfunction +< See https://gist.github.com/1610859 for a working example. + *'g:ctrlp_match_func'* +Set an external fuzzy matching function for |CtrlP| to use: > + let g:ctrlp_match_func = {} +< +Example: > + let g:ctrlp_match_func = { 'match': 'Function_Name' } +< +Structure of the function: > + function! Function_Name(items, str, limit, mmode, ispath, crfile, regex) + " Arguments: + " | + " +- a:items : The full list of items to search in. + " | + " +- a:str : The string entered by the user. + " | + " +- a:limit : The max height of the match window. Can be used to limit + " | the number of items to return. + " | + " +- a:mmode : The match mode. Can be one of these strings: + " | + "full-line": match the entire line. + " | + "filename-only": match only the filename. + " | + "first-non-tab": match until the first tab char. + " | + "until-last-tab": match until the last tab char. + " | + " +- a:ispath : Is 1 when searching in file, buffer, mru, dir, and rtscript + " | modes. Is 0 otherwise. + " | + " +- a:crfile : The file in the current window. Should be excluded from the + " | results when a:ispath == 1. + " | + " +- a:regex : In regex mode: 1 or 0. + + return list_of_matched_items + endfunction +< + =============================================================================== COMMANDS *ctrlp-commands* @@ -613,7 +676,8 @@ EXTENSIONS *g:ctrlp-extensions* Extensions are optional. To enable an extension, add its name to the variable g:ctrlp_extensions: > - let g:ctrlp_extensions = ['tag', 'buffertag', 'quickfix', 'dir', 'rtscript'] + let g:ctrlp_extensions = ['tag', 'buffertag', 'quickfix', 'dir', 'rtscript', + \ 'undo', 'line', 'changes'] < The order of the items will be the order they appear on the statusline and when using , . @@ -634,8 +698,8 @@ Available extensions:~ - Name: 'buffertag' - Commands: ':CtrlPBufTag [buffer-name]', ':CtrlPBufTagAll'. - - Search for a tag within the current buffer or all buffers and jump to the - definition. Requires |exuberant_ctags| or compatible programs. + - Search for a tag within the current buffer or all listed buffers and jump + to the definition. Requires |exuberant_ctags| or compatible programs. *:CtrlPQuickfix* * Quickfix mode:~ @@ -661,6 +725,27 @@ Available extensions:~ - Command: ':CtrlPRTS' - Search for files (vimscripts, docs, snippets...) in runtimepath. + *:CtrlPUndo* + * Undo mode:~ + - Name: 'undo' + - Command: ':CtrlPUndo' + - Browse undo history. + + *:CtrlPLine* + * Line mode:~ + - Name: 'line' + - Command: ':CtrlPLine' + - Search for a line in all listed buffers. + + *:CtrlPChange* + *:CtrlPChangeAll* + * Change list mode:~ + - Name: 'changes' + - Commands: ':CtrlPChange [buffer-name]', + ':CtrlPChangeAll'. + - Search for and jump to a recent change in the current buffer or in all + listed buffers. + ------------------------------------------------------------------------------- Buffer Tag mode options:~ @@ -703,10 +788,14 @@ Highlighting:~ * In extensions: CtrlPTabExtra : the part of each line that’s not matched against (Comment) - CtrlPqfLineCol : the line and column numbers in quickfix mode (|hl-Search|) + CtrlPBufName : the buffer name an entry belongs to (|hl-Directory|) + CtrlPTagKind : the kind of the tag in buffer-tag mode (|hl-Title|) + CtrlPqfLineCol : the line and column numbers in quickfix mode (Comment) CtrlPUndoT : the elapsed time in undo mode (|hl-Directory|) CtrlPUndoBr : the square brackets [] in undo mode (Comment) CtrlPUndoNr : the undo number inside [] in undo mode (String) + CtrlPUndoSv : the point where the file was saved (Comment) + CtrlPUndoPo : the current position in the undo tree (|hl-Title|) Statuslines:~ * Highlight groups: @@ -789,6 +878,7 @@ Special thanks:~ =============================================================================== CHANGELOG *ctrlp-changelog* + + New option: |g:ctrlp_match_func|, allow using a custom fuzzy matcher. + Rename: *ClearCtrlPCache* -> |CtrlPClearCache| *ClearAllCtrlPCaches* -> |CtrlPClearAllCaches| diff --git a/bundle/git_ctrlp/plugin/ctrlp.vim b/bundle/git_ctrlp/plugin/ctrlp.vim index 162a055..3868a44 100644 --- a/bundle/git_ctrlp/plugin/ctrlp.vim +++ b/bundle/git_ctrlp/plugin/ctrlp.vim @@ -65,4 +65,18 @@ if index(s:ext, 'rtscript') >= 0 com! CtrlPRTS cal ctrlp#init(ctrlp#rtscript#id()) en +if index(s:ext, 'undo') >= 0 + com! CtrlPUndo cal ctrlp#init(ctrlp#undo#id()) +en + +if index(s:ext, 'line') >= 0 + com! CtrlPLine cal ctrlp#init(ctrlp#line#id()) +en + +if index(s:ext, 'changes') >= 0 + com! -n=? -com=buffer CtrlPChange + \ cal ctrlp#init(ctrlp#changes#cmd(0, )) + com! CtrlPChangeAll cal ctrlp#init(ctrlp#changes#cmd(1)) +en + unl s:ext diff --git a/bundle/git_syntastic/plugin/syntastic.vim b/bundle/git_syntastic/plugin/syntastic.vim index 4e3486f..e2c56c9 100644 --- a/bundle/git_syntastic/plugin/syntastic.vim +++ b/bundle/git_syntastic/plugin/syntastic.vim @@ -374,7 +374,7 @@ function! s:HightlightErrors() let force_callback = has_key(item, 'force_highlight_callback') && item['force_highlight_callback'] let group = item['type'] == 'E' ? 'SyntasticError' : 'SyntasticWarning' - if item['col'] && !force_callback + if get( item, 'col' ) && !force_callback let lastcol = col([item['lnum'], '$']) let lcol = min([lastcol, item['col']]) call matchadd(group, '\%'.item['lnum'].'l\%'.lcol.'c') @@ -466,8 +466,8 @@ endfunction "load the chosen checker for the current filetype - useful for filetypes like "javascript that have more than one syntax checker -function! s:LoadChecker(checker) - exec "runtime syntax_checkers/" . &ft . "/" . a:checker . ".vim" +function! s:LoadChecker(checker, ft) + exec "runtime syntax_checkers/" . a:ft . "/" . a:checker . ".vim" endfunction "return a string representing the state of buffer according to @@ -602,22 +602,24 @@ endfunction "well as the names of the actual syntax checker executables. The checkers "should be listed in order of default preference. " -"if a option called 'g:syntastic_[filetype]_checker' exists then attempt to +"a:ft should be the filetype for the checkers being loaded +" +"if a option called 'g:syntastic_{a:ft}_checker' exists then attempt to "load the checker that it points to -function! SyntasticLoadChecker(checkers) - let opt_name = "g:syntastic_" . &ft . "_checker" +function! SyntasticLoadChecker(checkers, ft) + let opt_name = "g:syntastic_" . a:ft . "_checker" if exists(opt_name) let opt_val = {opt_name} if index(a:checkers, opt_val) != -1 && executable(opt_val) - call s:LoadChecker(opt_val) + call s:LoadChecker(opt_val, a:ft) else echoerr &ft . " syntax not supported or not installed." endif else for checker in a:checkers if executable(checker) - return s:LoadChecker(checker) + return s:LoadChecker(checker, a:ft) endif endfor endif diff --git a/bundle/git_syntastic/syntax_checkers/go.vim b/bundle/git_syntastic/syntax_checkers/go.vim index 395ae11..6d78b48 100644 --- a/bundle/git_syntastic/syntax_checkers/go.vim +++ b/bundle/git_syntastic/syntax_checkers/go.vim @@ -19,4 +19,4 @@ endif let loaded_go_syntax_checker = 1 let s:supported_checkers = ["6g", "gofmt"] -call SyntasticLoadChecker(s:supported_checkers) +call SyntasticLoadChecker(s:supported_checkers, 'go') diff --git a/bundle/git_syntastic/syntax_checkers/javascript.vim b/bundle/git_syntastic/syntax_checkers/javascript.vim index 026c737..3d5236c 100644 --- a/bundle/git_syntastic/syntax_checkers/javascript.vim +++ b/bundle/git_syntastic/syntax_checkers/javascript.vim @@ -20,4 +20,4 @@ endif let loaded_javascript_syntax_checker = 1 let s:supported_checkers = ["gjslint", "jslint", "jsl", "jshint"] -call SyntasticLoadChecker(s:supported_checkers) +call SyntasticLoadChecker(s:supported_checkers, 'javascript') diff --git a/bundle/git_syntastic/syntax_checkers/json.vim b/bundle/git_syntastic/syntax_checkers/json.vim index 2d2652d..1c2b3c9 100644 --- a/bundle/git_syntastic/syntax_checkers/json.vim +++ b/bundle/git_syntastic/syntax_checkers/json.vim @@ -20,4 +20,4 @@ endif let loaded_json_syntax_checker = 1 let s:supported_checkers = ["jsonlint", "jsonval"] -call SyntasticLoadChecker(s:supported_checkers) +call SyntasticLoadChecker(s:supported_checkers, 'json') diff --git a/bundle/git_syntastic/syntax_checkers/puppet.vim b/bundle/git_syntastic/syntax_checkers/puppet.vim index 51c898e..0ec02cb 100644 --- a/bundle/git_syntastic/syntax_checkers/puppet.vim +++ b/bundle/git_syntastic/syntax_checkers/puppet.vim @@ -19,21 +19,46 @@ if !executable("puppet") finish endif -function! s:ExtractVersion() +if !exists("g:syntastic_puppet_lint_disable") + let g:syntastic_puppet_lint_disable = 0 +endif + +if !executable("puppet-lint") + let g:syntastic_puppet_lint_disable = 0 +endif + +function! s:PuppetExtractVersion() let output = system("puppet --version") let output = substitute(output, '\n$', '', '') return split(output, '\.') endfunction -let s:puppetVersion = s:ExtractVersion() +function! s:PuppetLintExtractVersion() + let output = system("puppet-lint --version") + let output = substitute(output, '\n$', '', '') + let output = substitute(output, '^puppet-lint ', '', 'i') + return split(output, '\.') +endfunction -function! SyntaxCheckers_puppet_GetLocList() +let s:puppetVersion = s:PuppetExtractVersion() +let s:lintVersion = s:PuppetLintExtractVersion() + +if !(s:lintVersion[0] >= '0' && s:lintVersion[1] >= '1' && s:lintVersion[2] >= '10') + let g:syntastic_puppet_lint_disable = 0 +endif + +function! s:getPuppetLintErrors() + let makeprg = 'puppet-lint --log-format "\%{KIND} [\%{check}] \%{message} at \%{fullpath}:\%{linenumber}" '.shellescape(expand('%')) + let errorformat = '%t%*[a-zA-Z] %m at %f:%l' + return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat, 'subtype': 'Style' }) +endfunction + +function! s:getPuppetMakeprg() "If puppet is >= version 2.7 then use the new executable if s:puppetVersion[0] >= '2' && s:puppetVersion[1] >= '7' let makeprg = 'puppet parser validate ' . \ shellescape(expand('%')) . - \ ' --color=false' . - \ ' --storeconfigs' + \ ' --color=false' "add --ignoreimport for versions < 2.7.10 if s:puppetVersion[2] < '10' @@ -43,12 +68,24 @@ function! SyntaxCheckers_puppet_GetLocList() else let makeprg = 'puppet --color=false --parseonly --ignoreimport '.shellescape(expand('%')) endif + return makeprg +endfunction + +function! SyntaxCheckers_puppet_GetLocList() + + let makeprg = s:getPuppetMakeprg() "some versions of puppet (e.g. 2.7.10) output the message below if there "are any syntax errors let errorformat = '%-Gerr: Try ''puppet help parser validate'' for usage,' - let errorformat .= 'err: Could not parse for environment %*[a-z]: %m at %f:%l' - return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) + let errors = SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) + + if !g:syntastic_puppet_lint_disable + let errors = errors + s:getPuppetLintErrors() + endif + + return errors endfunction + diff --git a/bundle/git_syntastic/syntax_checkers/python.vim b/bundle/git_syntastic/syntax_checkers/python.vim index 93a0b52..863e064 100644 --- a/bundle/git_syntastic/syntax_checkers/python.vim +++ b/bundle/git_syntastic/syntax_checkers/python.vim @@ -24,4 +24,4 @@ if !exists('g:syntastic_python_checker_args') endif let s:supported_checkers = ["flake8", "pyflakes", "pylint"] -call SyntasticLoadChecker(s:supported_checkers) +call SyntasticLoadChecker(s:supported_checkers, 'python') diff --git a/bundle/git_syntastic/syntax_checkers/python/pylint.vim b/bundle/git_syntastic/syntax_checkers/python/pylint.vim index 62676f1..64adbc5 100644 --- a/bundle/git_syntastic/syntax_checkers/python/pylint.vim +++ b/bundle/git_syntastic/syntax_checkers/python/pylint.vim @@ -5,10 +5,10 @@ " "============================================================================ function! SyntaxCheckers_python_GetLocList() - let makeprg = 'pylint -f parseable -r n -i y ' . + let makeprg = 'pylint '.g:syntastic_python_checker_args.' -f parseable -r n -i y ' . \ shellescape(expand('%')) . - \ ' \| sed ''s_: \[[RC]_: \[W_''' . + \ ' 2>&1 \| sed ''s_: \[[RC]_: \[W_''' . \ ' \| sed ''s_: \[[F]_:\ \[E_''' - let errorformat = '%f:%l: [%t%n%.%#] %m,%-GNo config%m' + let errorformat = '%f:%l: [%t%n%.%#] %m,%f:%l: [%t%.%#] %m,%Z,%-GNo config%m' return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) endfunction diff --git a/bundle/git_syntastic/syntax_checkers/vala.vim b/bundle/git_syntastic/syntax_checkers/vala.vim index cf619f3..855ca04 100644 --- a/bundle/git_syntastic/syntax_checkers/vala.vim +++ b/bundle/git_syntastic/syntax_checkers/vala.vim @@ -6,6 +6,9 @@ " "// modules: " and containing space delimited list of vala " modules, used by the file, so this script can build correct " --pkg arguments. +" Alternatively you can set g:syntastic_vala_modules array +" in your .vimrc or .lvimrc with localvimrc plugin +" (http://www.vim.org/scripts/script.php?script_id=441). " Valac compiler is not the fastest thing in the world, so you " may want to disable this plugin with " let g:syntastic_vala_check_disabled = 1 command in your .vimrc or @@ -38,10 +41,19 @@ function! SyntaxCheckers_vala_GetHighlightRegex(pos) endfunction function! s:GetValaModules() + if exists('g:syntastic_vala_modules') + if type(g:syntastic_vala_modules) == type('') + return split(g:syntastic_vala_modules, '\s\+') + elseif type(g:syntastic_vala_modules) == type([]) + return g:syntastic_vala_modules + else + echoerr 'g:syntastic_vala_modules must be either list or string: fallback to in file modules string' + endif + endif + let modules_line = search('^// modules: ', 'n') let modules_str = getline(modules_line) - let modules = split(strpart(modules_str, 12), '\s\+') - return modules + return split(strpart(modules_str, 12), '\s\+') endfunction function! SyntaxCheckers_vala_GetLocList() diff --git a/bundle/git_taglisttoo/autoload/taglisttoo/lang/javascript.vim b/bundle/git_taglisttoo/autoload/taglisttoo/lang/javascript.vim index dbbce81..9f60a2c 100644 --- a/bundle/git_taglisttoo/autoload/taglisttoo/lang/javascript.vim +++ b/bundle/git_taglisttoo/autoload/taglisttoo/lang/javascript.vim @@ -1,7 +1,7 @@ " Author: Eric Van Dewoestine " " License: {{{ -" Copyright (c) 2005 - 2011, Eric Van Dewoestine +" Copyright (c) 2005 - 2012, Eric Van Dewoestine " All rights reserved. " " Redistribution and use of this software in source and binary forms, with @@ -122,7 +122,6 @@ function! s:ParseRegex(file, settings) " {{{ " prototype.js has Object.extend to extend existing objects. call add(patterns, ['o', '(?:var\s+)?\b([A-Z][A-Za-z0-9_.]+)\s*=\s*Object\.extend\s*\(', 1]) - call add(patterns, ['o', '\bObject\.extend\s*\(\b([A-Z][A-Za-z0-9_.]+)\s*,\s*\{', 1]) " mootools uses 'new Class' call add(patterns, ['o', '(?:var\s+)?\b([A-Z][A-Za-z0-9_.]+)\s*=\s*new\s+Class\s*\(', 1]) @@ -135,6 +134,11 @@ function! s:ParseRegex(file, settings) " {{{ " vimperator uses var = (function() call add(patterns, ['o', '([A-Za-z0-9_.]+)\s*=\s*\(function\s*\(', 1]) + " other library based exend calls (backbone, etc) + call add(patterns, + \ ['o', '(?:var\s+)?\b([A-Z][A-Za-z0-9_.]+)\s*=\s*[A-Za-z0-9_.]+\.extend\s*\({', 1]) + call add(patterns, ['o', '\.extend\s*\(\b([A-Z][A-Za-z0-9_.]+)\s*,\s*\{', 1]) + " Match Functions call add(patterns, ['f', '\bfunction\s+([a-zA-Z0-9_.\$]+?)\s*\(', 1]) call add(patterns, ['f', '([a-zA-Z0-9_.\$]+?)\s*=\s*function\s*\(', 1]) diff --git a/bundle/mark/autoload/mark.vim b/bundle/mark/autoload/mark.vim index 71a8bb4..474add6 100644 --- a/bundle/mark/autoload/mark.vim +++ b/bundle/mark/autoload/mark.vim @@ -1,123 +1,149 @@ " Script Name: mark.vim -" Description: Highlight several words in different colors simultaneously. +" Description: Highlight several words in different colors simultaneously. " " Copyright: (C) 2005-2008 by Yuheng Xie -" (C) 2008-2011 by Ingo Karkat -" The VIM LICENSE applies to this script; see ':help copyright'. +" (C) 2008-2012 by Ingo Karkat +" The VIM LICENSE applies to this script; see ':help copyright'. " -" Maintainer: Ingo Karkat +" Maintainer: Ingo Karkat " " Dependencies: -" - SearchSpecial.vim autoload script (optional, for improved search messages). +" - SearchSpecial.vim autoload script (optional, for improved search messages). " -" Version: 2.5.2 +" Version: 2.6.2 " Changes: +" 26-Mar-2012, Ingo Karkat +" - ENH: When a [count] exceeding the number of available mark groups is given, +" a summary of marks is given and the user is asked to select a mark group. +" This allows to interactively choose a color via 99m. +" - ENH: Include count of alternative patterns in :Marks list. +" - CHG: Use ">" for next mark and "/" for last search in :Marks. +" +" 23-Mar-2012, Ingo Karkat +" - ENH: Add :Marks command that prints all mark highlight groups and their +" search patterns, plus information about the current search mark, next mark +" group, and whether marks are disabled. +" - ENH: Show which mark group a pattern was set / added / removed / cleared. +" - Refactoring: Store index into s:pattern instead of pattern itself in +" s:lastSearch. For that, mark#CurrentMark() now additionally returns the +" index. +" - CHG: Show mark group number in same-mark search and rename search types from +" "any-mark", "same-mark", and "new-mark" to the shorter "mark-*", "mark-N", +" and "mark-N!", respectively. +" +" 22-Mar-2012, Ingo Karkat +" - ENH: Allow [count] for m and :Mark to add / subtract match to / from +" highlight group [count], and use [count]n to clear only highlight +" group [count]. This was also requested by Philipp Marek. +" - FIX: :Mark and n actually toggled marks back on when they were +" already off. Now, they stay off on multiple invocations. Use :call +" mark#Toggle() / MarkToggle if you want toggling. " " 09-Nov-2011, Ingo Karkat " - BUG: With a single match and 'wrapscan' set, a search error was issued " instead of the wrap message. Add check for l:isStuckAtCurrentMark && -" l:isWrapped in the no-match part of s:Search(). +" l:isWrapped in the no-match part of s:Search(). " - FIX: In backwards search with single match, the :break short-circuits the " l:isWrapped logic, resets l:line and therefore also confuses the logic and " leads to wrong error message instead of wrap message. Don't reset l:line, -" set l:isWrapped instead. +" set l:isWrapped instead. " - FIX: Wrong logic for determining l:isWrapped lets wrap-around go undetected " when v:count >= number of total matches. [l:startLine, l:startCol] must " be updated on every iteration, and should therefore be named [l:prevLine, -" l:prevCol]. +" l:prevCol]. " " 17-May-2011, Ingo Karkat " - Make s:GetVisualSelection() public to allow use in suggested -" MarkSpaceIndifferent vmap. +" MarkSpaceIndifferent vmap. " - FIX: == comparison in s:DoMark() leads to wrong regexp (\A vs. \a) being -" cleared when 'ignorecase' is set. Use case-sensitive comparison ==# instead. +" cleared when 'ignorecase' is set. Use case-sensitive comparison ==# instead. " " 10-May-2011, Ingo Karkat " - Refine :MarkLoad messages: Differentiate between nonexistent and empty -" g:MARK_MARKS; add note when marks are disabled. +" g:MARK_MARKS; add note when marks are disabled. " " 06-May-2011, Ingo Karkat -" - Also print status message on :MarkClear to be consistent with :MarkToggle. +" - Also print status message on :MarkClear to be consistent with :MarkToggle. " " 21-Apr-2011, Ingo Karkat " - Implement toggling of mark display (keeping the mark patterns, unlike the " clearing of marks), determined by s:enable. s:DoMark() now toggles on empty " regexp, affecting the \n mapping and :Mark. Introduced " s:EnableAndMarkScope() wrapper to correctly handle the highlighting updates -" depending on whether marks were previously disabled. -" - Implement persistence of s:enable via g:MARK_ENABLED. +" depending on whether marks were previously disabled. +" - Implement persistence of s:enable via g:MARK_ENABLED. " - Generalize s:Enable() and combine with intermediate s:Disable() into -" s:MarkEnable(), which also performs the persistence of s:enabled. +" s:MarkEnable(), which also performs the persistence of s:enabled. " - Implement lazy-loading of disabled persistent marks via g:mwDoDeferredLoad -" flag passed from plugin/mark.vim. +" flag passed from plugin/mark.vim. " " 20-Apr-2011, Ingo Karkat " - Extract setting of s:pattern into s:SetPattern() and implement the automatic -" persistence there. +" persistence there. " " 19-Apr-2011, Ingo Karkat " - ENH: Add enabling functions for mark persistence: mark#Load() and -" mark#ToPatternList(). +" mark#ToPatternList(). " - Implement :MarkLoad and :MarkSave commands in mark#LoadCommand() and -" mark#SaveCommand(). +" mark#SaveCommand(). " - Remove superfluous update autocmd on VimEnter: Persistent marks trigger the " update themselves, same for :Mark commands which could potentially be issued " e.g. in .vimrc. Otherwise, when no marks are defined after startup, the " autosource script isn't even loaded yet, so the autocmd on the VimEnter -" event isn't yet defined. +" event isn't yet defined. " " 18-Apr-2011, Ingo Karkat " - BUG: Include trailing newline character in check for current mark, so that a " mark that matches the entire line (e.g. created by Vm) can be -" cleared via n. Thanks to ping for reporting this. -" - Minor restructuring of mark#MarkCurrentWord(). +" cleared via n. Thanks to ping for reporting this. +" - Minor restructuring of mark#MarkCurrentWord(). " - FIX: On overlapping marks, mark#CurrentMark() returned the lowest, not the " highest visible mark. So on overlapping marks, the one that was not visible " at the cursor position was removed; very confusing! Use reverse iteration -" order. +" order. " - FIX: To avoid an arbitrary ordering of highlightings when the highlighting " group names roll over, and to avoid order inconsistencies across different " windows and tabs, we assign a different priority based on the highlighting -" group. +" group. " - Rename s:cycleMax to s:markNum; the previous name was too -" implementation-focused and off-by-one with regards to the actual value. +" implementation-focused and off-by-one with regards to the actual value. " " 16-Apr-2011, Ingo Karkat " - Move configuration variable g:mwHistAdd to plugin/mark.vim (as is customary) " and make the remaining g:mw... variables script-local, as these contain " internal housekeeping information that does not need to be accessible by the -" user. +" user. " - Add :MarkSave warning if 'viminfo' doesn't enable global variable -" persistence. +" persistence. " " 15-Apr-2011, Ingo Karkat " - Robustness: Move initialization of w:mwMatch from mark#UpdateMark() to " s:MarkMatch(), where the variable is actually used. I had encountered cases " where it w:mwMatch was undefined when invoked through mark#DoMark() -> " s:MarkScope() -> s:MarkMatch(). This can be forced by :unlet w:mwMatch -" followed by :Mark foo. +" followed by :Mark foo. " - Robustness: Checking for s:markNum == 0 in mark#DoMark(), trying to " re-detect the mark highlightings and finally printing an error instead of -" choking. This can happen when somehow no mark highlightings are defined. +" choking. This can happen when somehow no mark highlightings are defined. " " 14-Jan-2011, Ingo Karkat " - FIX: Capturing the visual selection could still clobber the blockwise yank -" mode of the unnamed register. +" mode of the unnamed register. " " 13-Jan-2011, Ingo Karkat " - FIX: Using a named register for capturing the visual selection on " {Visual}m and {Visual}r clobbered the unnamed register. Now -" using the unnamed register. +" using the unnamed register. " " 13-Jul-2010, Ingo Karkat " - ENH: The MarkSearch mappings ([*#/?]) add the original cursor " position to the jump list, like the built-in [/?*#nN] commands. This allows " to use the regular jump commands for mark matches, like with regular search -" matches. +" matches. " " 19-Feb-2010, Andy Wokula " - BUG: Clearing of an accidental zero-width match (e.g. via :Mark \zs) results -" in endless loop. Thanks to Andy Wokula for the patch. +" in endless loop. Thanks to Andy Wokula for the patch. " " 17-Nov-2009, Ingo Karkat + Andy Wokula " - BUG: Creation of literal pattern via '\V' in {Visual}m mapping @@ -127,354 +153,36 @@ " (overly) generic mark#GetVisualSelectionEscaped() with " mark#GetVisualSelectionAsRegexp() and " mark#GetVisualSelectionAsLiteralPattern(). Thanks to Andy Wokula for the -" patch. +" patch. " " 06-Jul-2009, Ingo Karkat -" - Re-wrote s:AnyMark() in functional programming style. +" - Re-wrote s:AnyMark() in functional programming style. " - Now resetting 'smartcase' before the search, this setting should not be " considered for *-command-alike searches and cannot be supported because all -" mark patterns are concatenated into one large regexp, anyway. +" mark patterns are concatenated into one large regexp, anyway. " " 04-Jul-2009, Ingo Karkat -" - Re-wrote s:Search() to handle v:count: +" - Re-wrote s:Search() to handle v:count: " - Obsoleted s:current_mark_position; mark#CurrentMark() now returns both the -" mark text and start position. +" mark text and start position. " - s:Search() now checks for a jump to the current mark during a backward -" search; this eliminates a lot of logic at its calling sites. -" - Reverted negative logic at calling sites; using empty() instead of != "". +" search; this eliminates a lot of logic at its calling sites. +" - Reverted negative logic at calling sites; using empty() instead of != "". " - Now passing a:isBackward instead of optional flags into s:Search() and -" around its callers. -" - ':normal! zv' moved from callers into s:Search(). +" around its callers. +" - ':normal! zv' moved from callers into s:Search(). " - Removed delegation to SearchSpecial#ErrorMessage(), because the fallback " implementation is perfectly fine and the SearchSpecial routine changed its -" output format into something unsuitable anyway. +" output format into something unsuitable anyway. " - Using descriptive text instead of "@" (and appropriate highlighting) when -" querying for the pattern to mark. +" querying for the pattern to mark. " " 02-Jul-2009, Ingo Karkat -" - Split off functions into autoload script. +" - Split off functions into autoload script. "- functions ------------------------------------------------------------------ -function! s:EscapeText( text ) - return substitute( escape(a:text, '\' . '^$.*[~'), "\n", '\\n', 'ge' ) -endfunction -" Mark the current word, like the built-in star command. -" If the cursor is on an existing mark, remove it. -function! mark#MarkCurrentWord() - let l:regexp = mark#CurrentMark()[0] - if empty(l:regexp) - let l:cword = expand('') - if ! empty(l:cword) - let l:regexp = s:EscapeText(l:cword) - " The star command only creates a \ search pattern if the - " actually only consists of keyword characters. - if l:cword =~# '^\k\+$' - let l:regexp = '\<' . l:regexp . '\>' - endif - endif - endif - if ! empty(l:regexp) - call mark#DoMark(l:regexp) - endif -endfunction - -function! mark#GetVisualSelection() - let save_clipboard = &clipboard - set clipboard= " Avoid clobbering the selection and clipboard registers. - let save_reg = getreg('"') - let save_regmode = getregtype('"') - silent normal! gvy - let res = getreg('"') - call setreg('"', save_reg, save_regmode) - let &clipboard = save_clipboard - return res -endfunction -function! mark#GetVisualSelectionAsLiteralPattern() - return s:EscapeText(mark#GetVisualSelection()) -endfunction -function! mark#GetVisualSelectionAsRegexp() - return substitute(mark#GetVisualSelection(), '\n', '', 'g') -endfunction - -" Manually input a regular expression. -function! mark#MarkRegex( regexpPreset ) - call inputsave() - echohl Question - let l:regexp = input('Input pattern to mark: ', a:regexpPreset) - echohl None - call inputrestore() - if ! empty(l:regexp) - call mark#DoMark(l:regexp) - endif -endfunction - -function! s:Cycle( ... ) - let l:currentCycle = s:cycle - let l:newCycle = (a:0 ? a:1 : s:cycle) + 1 - let s:cycle = (l:newCycle < s:markNum ? l:newCycle : 0) - return l:currentCycle -endfunction - -" Set match / clear matches in the current window. -function! s:MarkMatch( indices, expr ) - if ! exists('w:mwMatch') - let w:mwMatch = repeat([0], s:markNum) - endif - - for l:index in a:indices - if w:mwMatch[l:index] > 0 - silent! call matchdelete(w:mwMatch[l:index]) - let w:mwMatch[l:index] = 0 - endif - endfor - - if ! empty(a:expr) - let l:index = a:indices[0] " Can only set one index for now. - - " Info: matchadd() does not consider the 'magic' (it's always on), - " 'ignorecase' and 'smartcase' settings. - " Make the match according to the 'ignorecase' setting, like the star command. - " (But honor an explicit case-sensitive regexp via the /\C/ atom.) - let l:expr = ((&ignorecase && a:expr !~# '\\\@ 0 ? l:markCnt . ' ' : '') . 'marks' - endif -endfunction - - -" Mark or unmark a regular expression. -function! s:SetPattern( index, pattern ) - let s:pattern[a:index] = a:pattern - - if g:mwAutoSaveMarks - call s:SavePattern() - endif -endfunction -function! mark#ClearAll() - let i = 0 - let indices = [] - while i < s:markNum - if ! empty(s:pattern[i]) - call s:SetPattern(i, '') - call add(indices, i) - endif - let i += 1 - endwhile - let s:lastSearch = '' - -" Re-enable marks; not strictly necessary, since all marks have just been -" cleared, and marks will be re-enabled, anyway, when the first mark is added. -" It's just more consistent for mark persistence. But save the full refresh, as -" we do the update ourselves. - call s:MarkEnable(0, 0) - - call s:MarkScope(l:indices, '') - - if len(indices) > 0 - echo 'Cleared all' len(indices) 'marks' - else - echo 'All marks cleared' - endif -endfunction -function! mark#DoMark(...) " DoMark(regexp) - let regexp = (a:0 ? a:1 : '') - - " Disable marks if regexp is empty. Otherwise, we will be either removing a - " mark or adding one, so marks will be re-enabled. - if empty(regexp) - call mark#Toggle() - return - endif - - " clear the mark if it has been marked - let i = 0 - while i < s:markNum - if regexp ==# s:pattern[i] - if s:lastSearch ==# s:pattern[i] - let s:lastSearch = '' - endif - call s:SetPattern(i, '') - call s:EnableAndMarkScope([i], '') - return - endif - let i += 1 - endwhile - - if s:markNum <= 0 - " Uh, somehow no mark highlightings were defined. Try to detect them again. - call mark#Init() - if s:markNum <= 0 - " Still no mark highlightings; complain. - let v:errmsg = 'No mark highlightings defined' - echohl ErrorMsg - echomsg v:errmsg - echohl None - return - endif - endif - - " add to history - if stridx(g:mwHistAdd, '/') >= 0 - call histadd('/', regexp) - endif - if stridx(g:mwHistAdd, '@') >= 0 - call histadd('@', regexp) - endif - - " choose an unused mark group - let i = 0 - while i < s:markNum - if empty(s:pattern[i]) - call s:SetPattern(i, regexp) - call s:Cycle(i) - call s:EnableAndMarkScope([i], regexp) - return - endif - let i += 1 - endwhile - - " choose a mark group by cycle - let i = s:Cycle() - if s:lastSearch ==# s:pattern[i] - let s:lastSearch = '' - endif - call s:SetPattern(i, regexp) - call s:EnableAndMarkScope([i], regexp) -endfunction - -" Return [mark text, mark start position] of the mark under the cursor (or -" ['', []] if there is no mark). -" The mark can include the trailing newline character that concludes the line, -" but marks that span multiple lines are not supported. -function! mark#CurrentMark() - let line = getline('.') . "\n" - - " Highlighting groups with higher numbers take precedence over lower numbers, - " and therefore its marks appear "above" other marks. To retrieve the visible - " mark in case of overlapping marks, we need to check from highest to lowest - " highlighting group. - let i = s:markNum - 1 - while i >= 0 - if ! empty(s:pattern[i]) - " Note: col() is 1-based, all other indexes zero-based! - let start = 0 - while start >= 0 && start < strlen(line) && start < col('.') - let b = match(line, s:pattern[i], start) - let e = matchend(line, s:pattern[i], start) - if b < col('.') && col('.') <= e - return [s:pattern[i], [line('.'), (b + 1)]] - endif - if b == e - break - endif - let start = e - endwhile - endif - let i -= 1 - endwhile - return ['', []] -endfunction - -" Search current mark. -function! mark#SearchCurrentMark( isBackward ) - let [l:markText, l:markPosition] = mark#CurrentMark() - if empty(l:markText) - if empty(s:lastSearch) - call mark#SearchAnyMark(a:isBackward) - let s:lastSearch = mark#CurrentMark()[0] - else - call s:Search(s:lastSearch, a:isBackward, [], 'same-mark') - endif - else - call s:Search(l:markText, a:isBackward, l:markPosition, (l:markText ==# s:lastSearch ? 'same-mark' : 'new-mark')) - let s:lastSearch = l:markText - endif -endfunction - -silent! call SearchSpecial#DoesNotExist() " Execute a function to force autoload. +silent! call SearchSpecial#DoesNotExist() " Execute a function to force autoload. if exists('*SearchSpecial#WrapMessage') function! s:WrapMessage( searchType, searchPattern, isBackward ) redraw @@ -485,7 +193,7 @@ if exists('*SearchSpecial#WrapMessage') endfunction else function! s:Trim( message ) - " Limit length to avoid "Hit ENTER" prompt. + " Limit length to avoid "Hit ENTER" prompt. return strpart(a:message, 0, (&columns / 2)) . (len(a:message) > (&columns / 2) ? "..." : "") endfunction function! s:WrapMessage( searchType, searchPattern, isBackward ) @@ -503,6 +211,391 @@ else echon s:Trim(l:message) endfunction endif + +function! s:EscapeText( text ) + return substitute( escape(a:text, '\' . '^$.*[~'), "\n", '\\n', 'ge' ) +endfunction +" Mark the current word, like the built-in star command. +" If the cursor is on an existing mark, remove it. +function! mark#MarkCurrentWord( groupNum ) + let l:regexp = (a:groupNum == 0 ? mark#CurrentMark()[0] : '') + if empty(l:regexp) + let l:cword = expand('') + if ! empty(l:cword) + let l:regexp = s:EscapeText(l:cword) + " The star command only creates a \ search pattern if the + " actually only consists of keyword characters. + if l:cword =~# '^\k\+$' + let l:regexp = '\<' . l:regexp . '\>' + endif + endif + endif + return (empty(l:regexp) ? 0 : mark#DoMark(a:groupNum, l:regexp)) +endfunction + +function! mark#GetVisualSelection() + let save_clipboard = &clipboard + set clipboard= " Avoid clobbering the selection and clipboard registers. + let save_reg = getreg('"') + let save_regmode = getregtype('"') + silent normal! gvy + let res = getreg('"') + call setreg('"', save_reg, save_regmode) + let &clipboard = save_clipboard + return res +endfunction +function! mark#GetVisualSelectionAsLiteralPattern() + return s:EscapeText(mark#GetVisualSelection()) +endfunction +function! mark#GetVisualSelectionAsRegexp() + return substitute(mark#GetVisualSelection(), '\n', '', 'g') +endfunction + +" Manually input a regular expression. +function! mark#MarkRegex( regexpPreset ) + call inputsave() + echohl Question + let l:regexp = input('Input pattern to mark: ', a:regexpPreset) + echohl None + call inputrestore() + if ! empty(l:regexp) + call mark#DoMark(0, l:regexp) + endif +endfunction + +function! s:Cycle( ... ) + let l:currentCycle = s:cycle + let l:newCycle = (a:0 ? a:1 : s:cycle) + 1 + let s:cycle = (l:newCycle < s:markNum ? l:newCycle : 0) + return l:currentCycle +endfunction +function! s:FreeGroupIndex() + let i = 0 + while i < s:markNum + if empty(s:pattern[i]) + return i + endif + let i += 1 + endwhile + return -1 +endfunction + +" Set match / clear matches in the current window. +function! s:MarkMatch( indices, expr ) + if ! exists('w:mwMatch') + let w:mwMatch = repeat([0], s:markNum) + endif + + for l:index in a:indices + if w:mwMatch[l:index] > 0 + silent! call matchdelete(w:mwMatch[l:index]) + let w:mwMatch[l:index] = 0 + endif + endfor + + if ! empty(a:expr) + let l:index = a:indices[0] " Can only set one index for now. + + " Info: matchadd() does not consider the 'magic' (it's always on), + " 'ignorecase' and 'smartcase' settings. + " Make the match according to the 'ignorecase' setting, like the star command. + " (But honor an explicit case-sensitive regexp via the /\C/ atom.) + let l:expr = ((&ignorecase && a:expr !~# '\\\@ 0 ? l:markCnt . ' ' : '') . 'marks' + endif +endfunction + + +" Mark or unmark a regular expression. +function! s:SetPattern( index, pattern ) + let s:pattern[a:index] = a:pattern + + if g:mwAutoSaveMarks + call s:SavePattern() + endif +endfunction +function! mark#ClearAll() + let i = 0 + let indices = [] + while i < s:markNum + if ! empty(s:pattern[i]) + call s:SetPattern(i, '') + call add(indices, i) + endif + let i += 1 + endwhile + let s:lastSearch = -1 + +" Re-enable marks; not strictly necessary, since all marks have just been +" cleared, and marks will be re-enabled, anyway, when the first mark is added. +" It's just more consistent for mark persistence. But save the full refresh, as +" we do the update ourselves. + call s:MarkEnable(0, 0) + + call s:MarkScope(l:indices, '') + + if len(indices) > 0 + echo 'Cleared all' len(indices) 'marks' + else + echo 'All marks cleared' + endif +endfunction +function! s:SetMark( index, regexp, ... ) + if a:0 + if s:lastSearch == a:index + let s:lastSearch = a:1 + endif + endif + call s:SetPattern(a:index, a:regexp) + call s:EnableAndMarkScope([a:index], a:regexp) +endfunction +function! s:ClearMark( index ) + " A last search there is reset. + call s:SetMark(a:index, '', -1) +endfunction +function! s:EchoMark( groupNum, regexp ) + call s:EchoSearchPattern('mark-' . a:groupNum, a:regexp, 0) +endfunction +function! s:EchoMarkCleared( groupNum ) + echohl SearchSpecialSearchType + echo 'mark-' . a:groupNum + echohl None + echon ' cleared' +endfunction +function! s:EchoMarksDisabled() + echo 'All marks disabled' +endfunction +function! mark#DoMark( groupNum, ...) + if s:markNum <= 0 + " Uh, somehow no mark highlightings were defined. Try to detect them again. + call mark#Init() + if s:markNum <= 0 + " Still no mark highlightings; complain. + let v:errmsg = 'No mark highlightings defined' + echohl ErrorMsg + echomsg v:errmsg + echohl None + return 0 + endif + endif + + let l:groupNum = a:groupNum + if l:groupNum > s:markNum + " This highlight group does not exist. + let l:groupNum = mark#QueryMarkGroupNum() + if l:groupNum < 1 || l:groupNum > s:markNum + return 0 + endif + endif + + let regexp = (a:0 ? a:1 : '') + if empty(regexp) + if l:groupNum == 0 + " Disable all marks. + call s:MarkEnable(0) + call s:EchoMarksDisabled() + else + " Clear the mark represented by the passed highlight group number. + call s:ClearMark(l:groupNum - 1) + call s:EchoMarkCleared(l:groupNum) + endif + + return 1 + endif + + if l:groupNum == 0 + " Clear the mark if it has been marked. + let i = 0 + while i < s:markNum + if regexp ==# s:pattern[i] + call s:ClearMark(i) + call s:EchoMarkCleared(i + 1) + return 1 + endif + let i += 1 + endwhile + else + " Add / subtract the pattern as an alternative to the mark represented + " by the passed highlight group number. + let existingPattern = s:pattern[l:groupNum - 1] + if ! empty(existingPattern) + " Split only on \|, but not on \\|. + let alternatives = split(existingPattern, '\%(\%(^\|[^\\]\)\%(\\\\\)*\\\)\@= 0 + call histadd('/', regexp) + endif + if stridx(g:mwHistAdd, '@') >= 0 + call histadd('@', regexp) + endif + + if l:groupNum == 0 + let i = s:FreeGroupIndex() + if i != -1 + " Choose an unused highlight group. The last search is kept untouched. + call s:Cycle(i) + call s:SetMark(i, regexp) + else + " Choose a highlight group by cycle. A last search there is reset. + let i = s:Cycle() + call s:SetMark(i, regexp, -1) + endif + else + let i = l:groupNum - 1 + " Use and extend the passed highlight group. A last search is updated + " and thereby kept active. + call s:SetMark(i, regexp, i) + endif + + call s:EchoMark(i + 1, regexp) + return 1 +endfunction + +" Return [mark text, mark start position, mark index] of the mark under the +" cursor (or ['', [], -1] if there is no mark). +" The mark can include the trailing newline character that concludes the line, +" but marks that span multiple lines are not supported. +function! mark#CurrentMark() + let line = getline('.') . "\n" + + " Highlighting groups with higher numbers take precedence over lower numbers, + " and therefore its marks appear "above" other marks. To retrieve the visible + " mark in case of overlapping marks, we need to check from highest to lowest + " highlight group. + let i = s:markNum - 1 + while i >= 0 + if ! empty(s:pattern[i]) + " Note: col() is 1-based, all other indexes zero-based! + let start = 0 + while start >= 0 && start < strlen(line) && start < col('.') + let b = match(line, s:pattern[i], start) + let e = matchend(line, s:pattern[i], start) + if b < col('.') && col('.') <= e + return [s:pattern[i], [line('.'), (b + 1)], i] + endif + if b == e + break + endif + let start = e + endwhile + endif + let i -= 1 + endwhile + return ['', [], -1] +endfunction + +" Search current mark. +function! mark#SearchCurrentMark( isBackward ) + let [l:markText, l:markPosition, l:markIndex] = mark#CurrentMark() + if empty(l:markText) + if s:lastSearch == -1 + call mark#SearchAnyMark(a:isBackward) + let s:lastSearch = mark#CurrentMark()[2] + else + call s:Search(s:pattern[s:lastSearch], a:isBackward, [], 'mark-' . (s:lastSearch + 1)) + endif + else + call s:Search(l:markText, a:isBackward, l:markPosition, 'mark-' . (l:markIndex + 1) . (l:markIndex ==# s:lastSearch ? '' : '!')) + let s:lastSearch = l:markIndex + endif +endfunction + function! s:ErrorMessage( searchType, searchPattern, isBackward ) if &wrapscan let v:errmsg = a:searchType . ' not found: ' . a:searchPattern @@ -514,7 +607,7 @@ function! s:ErrorMessage( searchType, searchPattern, isBackward ) echohl None endfunction -" Wrapper around search() with additonal search and error messages and "wrapscan" warning. +" Wrapper around search() with additonal search and error messages and "wrapscan" warning. function! s:Search( pattern, isBackward, currentMarkPosition, searchType ) let l:save_view = winsaveview() @@ -523,7 +616,7 @@ function! s:Search( pattern, isBackward, currentMarkPosition, searchType ) " concatenated as branches in one large regexp, and because patterns that " result from the *-command-alike mappings should not obey 'smartcase' (like " the * command itself), anyway. If the :Mark command wants to support - " 'smartcase', it'd have to emulate that into the regular expression. + " 'smartcase', it'd have to emulate that into the regular expression. let l:save_smartcase = &smartcase set nosmartcase @@ -534,14 +627,14 @@ function! s:Search( pattern, isBackward, currentMarkPosition, searchType ) while l:count > 0 let [l:prevLine, l:prevCol] = [line('.'), col('.')] - " Search for next match, 'wrapscan' applies. + " Search for next match, 'wrapscan' applies. let [l:line, l:col] = searchpos( a:pattern, (a:isBackward ? 'b' : '') ) "****D echomsg '****' a:isBackward string([l:line, l:col]) string(a:currentMarkPosition) l:count if a:isBackward && l:line > 0 && [l:line, l:col] == a:currentMarkPosition && l:count == v:count1 " On a search in backward direction, the first match is the start of the " current mark (if the cursor was positioned on the current mark text, and - " not at the start of the mark text). + " not at the start of the mark text). " In contrast to the normal search, this is not considered the first " match. The mark text is one entity; if the cursor is positioned anywhere " inside the mark text, the mark text is considered the current mark. The @@ -549,14 +642,14 @@ function! s:Search( pattern, isBackward, currentMarkPosition, searchType ) " text is considered the current match, and jumps move outside that text. " In normal search, the cursor can be positioned anywhere (via offsets) " around the search, and only that single cursor position is considered - " the current match. + " the current match. " Thus, the search is retried without a decrease of l:count, but only if " this was the first match; repeat visits during wrapping around count as " a regular match. The search also must not be retried when this is the " first match, but we've been here before (i.e. l:isMatch is set): This " means that there is only the current mark in the buffer, and we must " break out of the loop and indicate that search wrapped around and no - " other mark was found. + " other mark was found. if l:isMatch let l:isWrapped = 1 break @@ -564,14 +657,14 @@ function! s:Search( pattern, isBackward, currentMarkPosition, searchType ) " The l:isMatch flag is set so if the final mark cannot be reached, the " original cursor position is restored. This flag also allows us to detect - " whether we've been here before, which is checked above. + " whether we've been here before, which is checked above. let l:isMatch = 1 elseif l:line > 0 let l:isMatch = 1 let l:count -= 1 " Note: No need to check 'wrapscan'; the wrapping can only occur if - " 'wrapscan' is actually on. + " 'wrapscan' is actually on. if ! a:isBackward && (l:prevLine > l:line || l:prevLine == l:line && l:prevCol >= l:col) let l:isWrapped = 1 elseif a:isBackward && (l:prevLine < l:line || l:prevLine == l:line && l:prevCol <= l:col) @@ -582,30 +675,30 @@ function! s:Search( pattern, isBackward, currentMarkPosition, searchType ) endif endwhile let &smartcase = l:save_smartcase - + " We're not stuck when the search wrapped around and landed on the current - " mark; that's why we exclude a possible wrap-around via v:count1 == 1. + " mark; that's why we exclude a possible wrap-around via v:count1 == 1. let l:isStuckAtCurrentMark = ([l:line, l:col] == a:currentMarkPosition && v:count1 == 1) "****D echomsg '****' l:line l:isStuckAtCurrentMark l:isWrapped l:isMatch string([l:line, l:col]) string(a:currentMarkPosition) if l:line > 0 && ! l:isStuckAtCurrentMark let l:matchPosition = getpos('.') - " Open fold at the search result, like the built-in commands. + " Open fold at the search result, like the built-in commands. normal! zv " Add the original cursor position to the jump list, like the - " [/?*#nN] commands. + " [/?*#nN] commands. " Implementation: Memorize the match position, restore the view to the state " before the search, then jump straight back to the match position. This " also allows us to set a jump only if a match was found. (:call - " setpos("''", ...) doesn't work in Vim 7.2) + " setpos("''", ...) doesn't work in Vim 7.2) call winrestview(l:save_view) normal! m' call setpos('.', l:matchPosition) " Enable marks (in case they were disabled) after arriving at the mark (to " avoid unnecessary screen updates) but before the error message (to avoid - " it getting lost due to the screen updates). + " it getting lost due to the screen updates). call s:MarkEnable(1) if l:isWrapped @@ -618,14 +711,14 @@ function! s:Search( pattern, isBackward, currentMarkPosition, searchType ) if l:isMatch " The view has been changed by moving through matches until the end / " start of file, when 'nowrapscan' forced a stop of searching before the - " l:count'th match was found. - " Restore the view to the state before the search. + " l:count'th match was found. + " Restore the view to the state before the search. call winrestview(l:save_view) endif " Enable marks (in case they were disabled) after arriving at the mark (to " avoid unnecessary screen updates) but before the error message (to avoid - " it getting lost due to the screen updates). + " it getting lost due to the screen updates). call s:MarkEnable(1) if l:line > 0 && l:isStuckAtCurrentMark && l:isWrapped @@ -638,26 +731,26 @@ function! s:Search( pattern, isBackward, currentMarkPosition, searchType ) endif endfunction -" Combine all marks into one regexp. +" Combine all marks into one regexp. function! s:AnyMark() return join(filter(copy(s:pattern), '! empty(v:val)'), '\|') endfunction -" Search any mark. +" Search any mark. function! mark#SearchAnyMark( isBackward ) let l:markPosition = mark#CurrentMark()[1] let l:markText = s:AnyMark() - call s:Search(l:markText, a:isBackward, l:markPosition, 'any-mark') - let s:lastSearch = "" + call s:Search(l:markText, a:isBackward, l:markPosition, 'mark-*') + let s:lastSearch = -1 endfunction -" Search last searched mark. +" Search last searched mark. function! mark#SearchNext( isBackward ) let l:markText = mark#CurrentMark()[0] if empty(l:markText) return 0 else - if empty(s:lastSearch) + if s:lastSearch == -1 call mark#SearchAnyMark(a:isBackward) else call mark#SearchCurrentMark(a:isBackward) @@ -666,11 +759,11 @@ function! mark#SearchNext( isBackward ) endif endfunction -" Load mark patterns from list. +" Load mark patterns from list. function! mark#Load( pattern, enabled ) if s:markNum > 0 && len(a:pattern) > 0 " Initialize mark patterns with the passed list. Ensure that, regardless of - " the list length, s:pattern contains exactly s:markNum elements. + " the list length, s:pattern contains exactly s:markNum elements. let s:pattern = a:pattern[0:(s:markNum - 1)] let s:pattern += repeat([''], (s:markNum - len(s:pattern))) @@ -678,18 +771,18 @@ function! mark#Load( pattern, enabled ) call mark#UpdateScope() - " The list of patterns may be sparse, return only the actual patterns. + " The list of patterns may be sparse, return only the actual patterns. return len(filter(copy(a:pattern), '! empty(v:val)')) endif return 0 endfunction -" Access the list of mark patterns. +" Access the list of mark patterns. function! mark#ToPatternList() " Trim unused patterns from the end of the list, the amount of available marks " may differ on the next invocation (e.g. due to a different number of " highlight groups in Vim and GVIM). We want to keep empty patterns in the - " front and middle to maintain the mapping to highlight groups, though. + " front and middle to maintain the mapping to highlight groups, though. let l:highestNonEmptyIndex = s:markNum -1 while l:highestNonEmptyIndex >= 0 && empty(s:pattern[l:highestNonEmptyIndex]) let l:highestNonEmptyIndex -= 1 @@ -698,12 +791,12 @@ function! mark#ToPatternList() return (l:highestNonEmptyIndex < 0 ? [] : s:pattern[0:l:highestNonEmptyIndex]) endfunction -" :MarkLoad command. +" :MarkLoad command. function! mark#LoadCommand( isShowMessages ) if exists('g:MARK_MARKS') try " Persistent global variables cannot be of type List, so we actually store - " the string representation, and eval() it back to a List. + " the string representation, and eval() it back to a List. execute 'let l:loadedMarkNum = mark#Load(' . g:MARK_MARKS . ', ' . (exists('g:MARK_ENABLED') ? g:MARK_ENABLED : 1) . ')' if a:isShowMessages if l:loadedMarkNum == 0 @@ -729,7 +822,7 @@ function! mark#LoadCommand( isShowMessages ) endif endfunction -" :MarkSave command. +" :MarkSave command. function! s:SavePattern() let l:savedMarks = mark#ToPatternList() let g:MARK_MARKS = string(l:savedMarks) @@ -754,6 +847,85 @@ function! mark#SaveCommand() endfunction +" Query mark group number. +function! s:GetNextGroupIndex() + let l:nextGroupIndex = s:FreeGroupIndex() + if l:nextGroupIndex == -1 + let l:nextGroupIndex = s:cycle + endif + return l:nextGroupIndex +endfunction +function! s:GetMarker( index, nextGroupIndex ) + let l:marker = '' + if s:lastSearch == a:index + let l:marker .= '/' + endif + if a:index == a:nextGroupIndex + let l:marker .= '>' + endif + return l:marker +endfunction +function! s:GetAlternativeCount( pattern ) + return len(split(a:pattern, '\%(\%(^\|[^\\]\)\%(\\\\\)*\\\)\@ 1 ? c : '') . '*' : ''), (i + 1)) + echohl None + endfor +endfunction +function! mark#QueryMarkGroupNum() + echohl Question + echo 'Mark?' + echohl None + let l:nextGroupIndex = s:GetNextGroupIndex() + call s:PrintMarkGroup(l:nextGroupIndex) + + let l:nr = 0 + while 1 + let l:char = nr2char(getchar()) + + if l:char ==# "\" + return (l:nr == 0 ? l:nextGroupIndex + 1 : l:nr) + elseif l:char !~# '\d' + return -1 + endif + echon l:char + + let l:nr = 10 * l:nr + l:char + if s:markNum < 10 * l:nr + return l:nr + endif + endwhile +endfunction + +" :Marks command. +function! mark#List() + echohl Title + echo 'mark cnt Pattern' + echohl None + echon ' (> next mark group / current search mark)' + let l:nextGroupIndex = s:GetNextGroupIndex() + for i in range(s:markNum) + execute 'echohl MarkWord' . (i + 1) + let c = s:GetAlternativeCount(s:pattern[i]) + echo printf('%1s%3d%4s %s', s:GetMarker(i, l:nextGroupIndex), (i + 1), (c > 1 ? '('.c.')' : ''), s:pattern[i]) + echohl None + endfor + + if ! s:enabled + echo 'Marks are currently disabled.' + endif +endfunction + +function! mark#GetGroupNum() + return s:markNum +endfunction + + "- initializations ------------------------------------------------------------ augroup Mark autocmd! @@ -761,7 +933,7 @@ augroup Mark autocmd TabEnter * call mark#UpdateScope() augroup END -" Define global variables and initialize current scope. +" Define global variables and initialize current scope. function! mark#Init() let s:markNum = 0 while hlexists('MarkWord' . (s:markNum + 1)) @@ -769,7 +941,7 @@ function! mark#Init() endwhile let s:pattern = repeat([''], s:markNum) let s:cycle = 0 - let s:lastSearch = '' + let s:lastSearch = -1 let s:enabled = 1 endfunction @@ -781,4 +953,4 @@ else call mark#UpdateScope() endif -" vim: ts=2 sw=2 +" vim: ts=4 sts=0 sw=4 noet diff --git a/bundle/mark/doc/mark.txt b/bundle/mark/doc/mark.txt index 1bd4080..8bf9fd2 100644 --- a/bundle/mark/doc/mark.txt +++ b/bundle/mark/doc/mark.txt @@ -1,4 +1,4 @@ -*mark.txt* Highlight several words in different colors simultaneously. +*mark.txt* Highlight several words in different colors simultaneously. MARK by Ingo Karkat (original version by Yuheng Xie) @@ -26,25 +26,27 @@ doesn't maintain his original version anymore and cannot be reached via the email address in his profile. This plugin offers the following advantages over the original: - Much faster, all colored words can now be highlighted, no more clashes with - syntax highlighting (due to use of matchadd()). -- Many bug fixes. -- Jumps behave like the built-in search, including wrap and error messages. + syntax highlighting (due to use of matchadd()). +- Many bug fixes. +- Jumps behave like the built-in search, including wrap and error messages. - Like the built-in commands, jumps take an optional [count] to quickly skip - over some marks. + over some marks. +- Marks can be persisted, and patterns can be added / subtracted from + mark highlight groups. RELATED WORKS * - MultipleSearch (vimscript #479) can highlight in a single window and in all buffers, but still relies on the :syntax highlighting method, which is - slower and less reliable. + slower and less reliable. - http://vim.wikia.com/wiki/Highlight_multiple_words offers control over the color used by mapping the 1-9 keys on the numeric keypad, persistence, and - highlights only a single window. + highlights only a single window. - highlight.vim (vimscript #1599) highlights lines or patterns of interest in - different colors, using mappings that start with CTRL-H and work on cword. + different colors, using mappings that start with CTRL-H and work on cword. - quickhl.vim (vimscript #3692) can also list the matches with colors and in addition offers on-the-fly highlighting of the current word (like many IDEs - do). + do). ============================================================================== USAGE *mark-usage* @@ -52,38 +54,68 @@ USAGE *mark-usage* HIGHLIGHTING *mark-highlighting* *m* *v_m* m Mark the word under the cursor, similar to the |star| - command. The next free highlight group is used. + command. The next free highlight group is used. If already on a mark: Clear the mark, like - |n|. -{Visual}m Mark or unmark the visual selection. + |n|. +{Visual}m Mark or unmark the visual selection. +[N]m With [N], mark the word under the cursor with the + named highlight group [N]. When that group is not + empty, the word is added as an alternative match, so + you can highlight multiple words with the same color. + When the word is already contained in the list of + alternatives, it is removed. + + When [N] is greater than the number of defined mark + groups, a summary of marks is printed. Active mark + groups are prefixed with "*" (or "M*" when there are + M pattern alternatives), the default next group with + ">", the last used search with "/" (like |:Marks| + does). Input the mark group, accept the default with + , or abort with or any other key. + This way, when unsure about which number represents + which color, just use 99n and pick the color + interactively! + +{Visual}[N]m Ditto, based on the visual selection. + *r* *v_r* -r Manually input a regular expression to mark. -{Visual}r Ditto, based on the visual selection. +r Manually input a regular expression to mark. +{Visual}r Ditto, based on the visual selection. In accordance with the built-in |star| command, all these mappings use 'ignorecase', but not - 'smartcase'. + 'smartcase'. *n* n Clear the mark under the cursor. If not on a mark: Disable all marks, similar to - |:nohlsearch|. - + |:nohlsearch|. Note: Marks that span multiple lines are not detected, so the use of n on such a mark will unintentionally remove all marks! Use {Visual}r or :Mark {pattern} to clear - multi-line marks. + multi-line marks (or pass [N] if you happen to know + the group number). +[N]n Clear the marks represented by highlight group [N]. + *:Mark* -:Mark {pattern} Mark or unmark {pattern}. +:[N]Mark Clear the marks represented by highlight group [N]. +:[N]Mark {pattern} Mark or unmark {pattern}. Unless [N] is given, the + next free highlight group is used. + With [N], mark the word under the cursor with the + named highlight group [N]. When that group is not + empty, the word is added as an alternative match, so + you can highlight multiple words with the same color. + When the word is already contained in the list of + alternatives, it is removed. For implementation reasons, {pattern} cannot use the - 'smartcase' setting, only 'ignorecase'. + 'smartcase' setting, only 'ignorecase'. :Mark Disable all marks, similar to |:nohlsearch|. Marks will automatically re-enable when a mark is added or - removed, or a search for marks is performed. + removed, or a search for marks is performed. *:MarkClear* :MarkClear Clear all marks. In contrast to disabling marks, the actual mark information is cleared, the next mark will - use the first highlight group. This cannot be undone. + use the first highlight group. This cannot be undone. SEARCHING *mark-searching* @@ -92,63 +124,79 @@ SEARCHING *mark-searching* [count]* [count]# [count]/ [count]? Use these six keys to jump to the [count]'th next / - previous occurrence of a mark. + previous occurrence of a mark. You could also use Vim's / and ? to search, since the mark patterns are (optionally, see configuration) - added to the search history, too. + added to the search history, too. 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". + current mark, and remember it "last mark". + as "last mark". - / Jump to the next occurrence of Same as left. - ANY mark. + / Jump to the next occurrence of Same as left. + ANY mark. - * If * is the most recently Do Vim's original * command. + * If * is the most recently Do Vim's original * command. used, do a *; otherwise (/ is the most recently - used), do a /. + used), do a /. Note: When the cursor is on a mark, the backwards search does not jump to the beginning of the current mark (like the built-in search), but to the previous - mark. The entire mark text is treated as one entity. + mark. The entire mark text is treated as one entity. You can use Vim's |jumplist| to go back to previous - mark matches and the position before a mark search. + mark matches and the position before a mark search. MARK PERSISTENCE *mark-persistence* The marks can be kept and restored across Vim sessions, using the |viminfo| file. For this to work, the "!" flag must be part of the 'viminfo' setting: > - set viminfo+=! " Save and restore global variables. + set viminfo+=! " Save and restore global variables. < *:MarkLoad* :MarkLoad Restore the marks from the previous Vim session. All - current marks are discarded. + current marks are discarded. *:MarkSave* :MarkSave Save the currently defined marks (or clear the persisted marks if no marks are currently defined) for - use in a future Vim session. + use in a future Vim session. By default, automatic persistence is enabled (so you don't need to explicitly |:MarkSave|), but you have to explicitly load the persisted marks in a new Vim session via |:MarkLoad|, to avoid that you accidentally drag along outdated highlightings from Vim session to session, and be surprised by the arbitrary highlight groups and occasional appearance of forgotten marks. If you want -just that though and automatically restore any marks, set |g:mwAutoLoadMarks|. +just that though and automatically restore any marks, set |g:mwAutoLoadMarks|. -You can also initialize the marks to static values, e.g. by including this in -|vimrc|: > +You can also initialize some marks (even using particular highlight groups) to +static values, e.g. by including this in |vimrc|: > runtime plugin/mark.vim silent MarkClear - Mark foo - Mark bar + 5Mark foo + 6Mark bar Or you can define custom commands that preset certain marks: > - command -bar MyMarks silent MarkClear | execute 'Mark foo' | execute 'Mark bar' + command -bar MyMarks silent MarkClear | execute '5Mark foo' | execute '6Mark bar' Or a command that adds to the existing marks and then toggles them: > command -bar ToggleFooBarMarks execute 'Mark foo' | execute 'Mark bar' +< +MARK INFORMATION *mark-information* + +Both |mark-highlighting| and |mark-searching| commands print information about +the mark and search pattern, e.g. + mark-1/\ ~ +This is especially useful when you want to add or subtract patterns to a mark +highlight group via [N]. + + *:Marks* +:Marks List all mark highlight groups and the search patterns + defined for them. + The group that will be used for the next |:Mark| or + |m| command (with [N]) is shown with a ">". + The last mark used for a search (via |*|) is + shown with a "/". ============================================================================== INSTALLATION *mark-installation* @@ -159,26 +207,26 @@ the archive first, e.g. using WinZip. Inside Vim, install by sourcing the vimball or via the |:UseVimball| command. > vim mark.vba.gz :so % -To uninstall, use the |:RmVimball| command. +To uninstall, use the |:RmVimball| command. DEPENDENCIES *mark-dependencies* -- Requires Vim 7.1 with "matchadd()", or Vim 7.2 or higher. +- Requires Vim 7.1 with "matchadd()", or Vim 7.2 or higher. ============================================================================== CONFIGURATION *mark-configuration* -For a permanent configuration, put the following commands into your |vimrc|. +For a permanent configuration, put the following commands into your |vimrc|. *mark-highlight-colors* You may define your own colors or more than the default 6 highlightings in your vimrc file (or anywhere before this plugin is sourced), in the following form (where N = 1..): > highlight MarkWordN ctermbg=Cyan ctermfg=Black guibg=#8CCBEA guifg=Black -Higher numbers always take precedence and are displayed above lower ones. +Higher numbers always take precedence and are displayed above lower ones. If you want to avoid losing the highlightings on |:colorscheme| commands, you need to re-apply your highlights on the |ColorScheme| event, similar to how -this plugin does. +this plugin does. The search type highlighting (in the search message) can be changed via: > highlight link SearchSpecialSearchType MoreMsg @@ -194,11 +242,11 @@ To enable the automatic restore of marks from a previous Vim session: > < *g:mwAutoSaveMarks* To turn off the automatic persistence of marks across Vim sessions: > let g:mwAutoSaveMarks = 0 -You can still explicitly save marks via |:MarkSave|. +You can still explicitly save marks via |:MarkSave|. *mark-mappings* You can use different mappings by mapping to the Mark... mappings (use -":map Mark" to list them all) before this plugin is sourced. +":map Mark" to list them all) before this plugin is sourced. There are no default mappings for toggling all marks and for the |:MarkClear| command, but you can define some yourself: > @@ -214,7 +262,7 @@ Some people like to create a mark based on the visual selection, like |v_m|, but have whitespace in the selection match any whitespace when searching (searching for "hello world" will also find "helloworld" as well as "hello" at the end of a line, with "world" at the start of the next -line). The Vim Tips Wiki describes such a setup for the built-in search at +line). The Vim Tips Wiki describes such a setup for the built-in search at http://vim.wikia.com/wiki/Search_for_visually_selected_text You can achieve the same with the Mark plugin through the following scriptlet: > function! s:GetVisualSelectionAsLiteralWhitespaceIndifferentPattern() @@ -232,11 +280,11 @@ behavior: > LIMITATIONS *mark-limitations* - If the 'ignorecase' setting is changed, there will be discrepancies between - the highlighted marks and subsequent jumps to marks. + the highlighted marks and subsequent jumps to marks. - If {pattern} in a :Mark command contains atoms that change the semantics of the entire (|/\c|, |/\C|) or following (|/\v|,|/\V|, |/\M|) regular expression, there may be discrepancies between the highlighted marks and - subsequent jumps to marks. + subsequent jumps to marks. KNOWN PROBLEMS *mark-known-problems* @@ -245,103 +293,130 @@ TODO *mark-todo* IDEAS *mark-ideas* Taken from an alternative implementation at -http://vim.wikia.com/wiki/Highlight_multiple_words: -- Allow to specify the highlight group number via :[N]Mark {regexp} -- Use keys 1-9 on the numeric keypad to toggle a highlight group number. +http://vim.wikia.com/wiki/Highlight_multiple_words: +- Use keys 1-9 on the numeric keypad to toggle a highlight group number. ============================================================================== HISTORY *mark-history* +2.6.2 26-Mar-2012 +- ENH: When a [count] exceeding the number of available mark groups is given, + a summary of marks is given and the user is asked to select a mark group. + This allows to interactively choose a color via 99m. +- ENH: Include count of alternative patterns in :Marks list. +- CHG: Use ">" for next mark and "/" for last search in :Marks. + +2.6.1 23-Mar-2012 +- ENH: Add :Marks command that prints all mark highlight groups and their + search patterns, plus information about the current search mark, next mark + group, and whether marks are disabled. +- ENH: Show which mark group a pattern was set / added / removed / cleared. +- FIX: When the cursor is positioned on the current mark, [N]n / + MarkClear with [N] appended the pattern for the current mark (again + and again) instead of clearing it. Must not pass current mark pattern when + [N] is given. +- CHG: Show mark group number in same-mark search and rename search types from + "any-mark", "same-mark", and "new-mark" to the shorter "mark-*", "mark-N", + and "mark-N!", respectively. + +2.6.0 22-Mar-2012 +- ENH: Allow [count] for m and :Mark to add / subtract match to / from + highlight group [count], and use [count]n to clear only highlight + group [count]. This was also requested by Philipp Marek. +- FIX: :Mark and n actually toggled marks back on when they were + already off. Now, they stay off on multiple invocations. Use :call + mark#Toggle() / MarkToggle if you want toggling. + 2.5.3 02-Mar-2012 - BUG: Version check mistakenly excluded Vim 7.1 versions that do have the - matchadd() function. Thanks to Philipp Marek for sending a patch. + matchadd() function. Thanks to Philipp Marek for sending a patch. 2.5.2 09-Nov-2011 -Fixed various problems with wrap-around warnings: -- BUG: With a single match and 'wrapscan' set, a search error was issued. +Fixed various problems with wrap-around warnings: +- BUG: With a single match and 'wrapscan' set, a search error was issued. - FIX: Backwards search with single match leads to wrong error message - instead. -- FIX: Wrong logic for determining l:isWrapped lets wrap-around go undetected. + instead. +- FIX: Wrong logic for determining l:isWrapped lets wrap-around go undetected. 2.5.1 17-May-2011 - FIX: == comparison in s:DoMark() leads to wrong regexp (\A vs. \a) being - cleared when 'ignorecase' is set. Use case-sensitive comparison ==# instead. -- Refine :MarkLoad messages + cleared when 'ignorecase' is set. Use case-sensitive comparison ==# instead. +- Refine :MarkLoad messages - Add whitespace-indifferent visual mark configuration example. Thanks to Greg - Klein for the suggestion. + Klein for the suggestion. 2.5.0 07-May-2011 - ENH: Add explicit mark persistence via :MarkLoad and :MarkSave commands and automatic persistence via the g:mwAutoLoadMarks and g:mwAutoSaveMarks - configuration flags. (Request from Mun Johl, 16-Apr-2010) + configuration flags. (Request from Mun Johl, 16-Apr-2010) - Expose toggling of mark display (keeping the mark patterns) via new MarkToggle mapping. Offer :MarkClear command as a replacement for the old argumentless :Mark command, which now just disables, but not clears all - marks. + marks. 2.4.4 18-Apr-2011 - BUG: Include trailing newline character in check for current mark, so that a mark that matches the entire line (e.g. created by Vm) can be - cleared via n. Thanks to ping for reporting this. + cleared via n. Thanks to ping for reporting this. - FIX: On overlapping marks, mark#CurrentMark() returned the lowest, not the highest visible mark. So on overlapping marks, the one that was not visible at the cursor position was removed; very confusing! Use reverse iteration - order. + order. - FIX: To avoid an arbitrary ordering of highlightings when the highlighting group names roll over, and to avoid order inconsistencies across different windows and tabs, we assign a different priority based on the highlighting - group. + group. 2.4.3 16-Apr-2011 - Avoid losing the mark highlightings on :syn on or :colorscheme commands. - Thanks to Zhou YiChao for alerting me to this issue and suggesting a fix. + Thanks to Zhou YiChao for alerting me to this issue and suggesting a fix. - Made the script more robust when somehow no highlightings have been defined or when the window-local reckoning of match IDs got lost. I had very - occasionally encountered such script errors in the past. + occasionally encountered such script errors in the past. - Made global housekeeping variables script-local, only g:mwHistAdd is used - for configuration. + for configuration. 2.4.2 14-Jan-2011 (unreleased) - FIX: Capturing the visual selection could still clobber the blockwise yank - mode of the unnamed register. + mode of the unnamed register. 2.4.1 13-Jan-2011 - FIX: Using a named register for capturing the visual selection on {Visual}m and {Visual}r clobbered the unnamed register. Now - using the unnamed register. + using the unnamed register. 2.4.0 13-Jul-2010 - ENH: The MarkSearch mappings ([*#/?]) add the original cursor position to the jump list, like the built-in [/?*#nN] commands. This allows to use the regular jump commands for mark matches, like with regular search - matches. + matches. 2.3.3 19-Feb-2010 - BUG: Clearing of an accidental zero-width match (e.g. via :Mark \zs) results - in endless loop. Thanks to Andy Wokula for the patch. + in endless loop. Thanks to Andy Wokula for the patch. 2.3.2 17-Nov-2009 - BUG: Creation of literal pattern via '\V' in {Visual}m mapping collided with individual escaping done in m mapping so that an escaped '\*' would be interpreted as a multi item when both modes are used - for marking. Thanks to Andy Wokula for the patch. + for marking. Thanks to Andy Wokula for the patch. 2.3.1 06-Jul-2009 - Now working correctly when 'smartcase' is set. All mappings and the :Mark - command use 'ignorecase', but not 'smartcase'. + command use 'ignorecase', but not 'smartcase'. 2.3.0 04-Jul-2009 - All jump commands now take an optional [count], so you can quickly skip over some marks, as with the built-in */# and n/N commands. For this, the entire core search algorithm has been rewritten. The script's logic has been - simplified through the use of Vim 7 features like Lists. -- Now also printing a Vim-alike search error message when 'nowrapscan' is set. + simplified through the use of Vim 7 features like Lists. +- Now also printing a Vim-alike search error message when 'nowrapscan' is set. 2.2.0 02-Jul-2009 -- Split off functions into autoload script. +- Split off functions into autoload script. - Initialization of global variables and autocommands is now done lazily on the first use, not during loading of the plugin. This reduces Vim startup - time and footprint as long as the functionality isn't yet used. + time and footprint as long as the functionality isn't yet used. - Split off documentation into separate help file. Now packaging as VimBall. @@ -349,37 +424,37 @@ Fixed various problems with wrap-around warnings: - Replaced highlighting via :syntax with matchadd() / matchdelete(). This requires Vim 7.2 / 7.1 with patches. This method is faster, there are no more clashes with syntax highlighting (:match always has preference), and - the background highlighting does not disappear under 'cursorline'. + the background highlighting does not disappear under 'cursorline'. - Using winrestcmd() to fix effects of :windo: By entering a window, its - height is potentially increased from 0 to 1. -- Handling multiple tabs by calling s:UpdateScope() on the TabEnter event. + height is potentially increased from 0 to 1. +- Handling multiple tabs by calling s:UpdateScope() on the TabEnter event. 2.0.0 01-Jun-2009 - Now using Vim List for g:mwWord and thus requiring Vim 7. g:mwCycle is now - zero-based, but the syntax groups "MarkWordx" are still one-based. + zero-based, but the syntax groups "MarkWordx" are still one-based. - Factored :syntax operations out of s:DoMark() and s:UpdateMark() so that - they can all be done in a single :windo. + they can all be done in a single :windo. - Normal mode MarkSet now has the same semantics as its visual mode cousin: If the cursor is on an existing mark, the mark is removed. Beforehand, one could only remove a visually selected mark via again - selecting it. Now, one simply can invoke the mapping when on such a mark. + selecting it. Now, one simply can invoke the mapping when on such a mark. 1.6.1 31-May-2009 -Publication of improved version by Ingo Karkat. +Publication of improved version by Ingo Karkat. - Now prepending search type ("any-mark", "same-mark", "new-mark") for better - identification. + identification. - Retired the algorithm in s:PrevWord in favor of simply using , which makes mark.vim work like the * command. At the end of a line, non-keyword characters may now be marked; the previous algorithm preferred any preceding - word. + word. - BF: If 'iskeyword' contains characters that have a special meaning in a - regexp (e.g. [.*]), these are now escaped properly. + regexp (e.g. [.*]), these are now escaped properly. - Highlighting can now actually be overridden in the vimrc (anywhere _before_ - sourcing this script) by using ':hi def'. -- Added missing setter for re-inclusion guard. + sourcing this script) by using ':hi def'. +- Added missing setter for re-inclusion guard. 1.5.0 01-Sep-2008 -Bug fixes and enhancements by Ingo Karkat. +Bug fixes and enhancements by Ingo Karkat. - Added MarkAllClear (without a default mapping), which clears all marks, even when the cursor is on a mark. - Added ... mappings for hard-coded \*, \#, \/, \?, * and #, to allow @@ -395,18 +470,18 @@ Bug fixes and enhancements by Ingo Karkat. continuing at TOP" and "Pattern not found:..." messages, like the * and n/N Vim search commands. - ENH: Jumps now open folds if the occurrence is inside a closed fold, just - like n/N do. + like n/N do. 1.1.8-g 25-Apr-2008 -Last version published by Yuheng Xie on vim.org. +Last version published by Yuheng Xie on vim.org. 1.1.2 22-Mar-2005 -Initial version published by Yuheng Xie on vim.org. +Initial version published by Yuheng Xie on vim.org. ============================================================================== Copyright: (C) 2005-2008 Yuheng Xie (C) 2008-2012 Ingo Karkat -The VIM LICENSE applies to this script; see|copyright|. +The VIM LICENSE applies to this script; see|copyright|. Maintainer: Ingo Karkat ============================================================================== diff --git a/bundle/mark/plugin/mark.vim b/bundle/mark/plugin/mark.vim index 4bd2c1b..94b944b 100644 --- a/bundle/mark/plugin/mark.vim +++ b/bundle/mark/plugin/mark.vim @@ -1,111 +1,125 @@ " Script Name: mark.vim -" Description: Highlight several words in different colors simultaneously. +" Description: Highlight several words in different colors simultaneously. " " Copyright: (C) 2005-2008 Yuheng Xie " (C) 2008-2012 Ingo Karkat -" The VIM LICENSE applies to this script; see ':help copyright'. +" The VIM LICENSE applies to this script; see ':help copyright'. " -" Maintainer: Ingo Karkat +" Maintainer: Ingo Karkat " Orig Author: Yuheng Xie " Contributors:Luc Hermitte, Ingo Karkat " " Dependencies: -" - Requires Vim 7.1 with "matchadd()", or Vim 7.2 or higher. -" - mark.vim autoload script. -" -" Version: 2.5.3 +" - Requires Vim 7.1 with "matchadd()", or Vim 7.2 or higher. +" - mark.vim autoload script. +" +" Version: 2.6.1 " Changes: +" 23-Mar-2012, Ingo Karkat +" - ENH: Add :Marks command that prints all mark highlight groups and their +" search patterns, plus information about the current search mark, next mark +" group, and whether marks are disabled. +" - FIX: When the cursor is positioned on the current mark, [N]n / +" MarkClear with [N] appended the pattern for the current mark (again +" and again) instead of clearing it. Must not pass current mark pattern when +" [N] is given. +" +" 22-Mar-2012, Ingo Karkat +" - ENH: Allow [count] for m and :Mark to add / subtract match to / from +" highlight group [count], and use [count]n to clear only highlight +" group [count]. This was also requested by Philipp Marek. +" " 02-Mar-2012, Philipp Marek " - BUG: Version check mistakenly excluded Vim 7.1 versions that do have the -" matchadd() function. +" matchadd() function. " " 06-May-2011, Ingo Karkat " - By default, enable g:mwAutoSaveMarks, so that marks are always persisted, " but disable g:mwAutoLoadMarks, so that persisted marks have to be explicitly " loaded, if that is desired. I often wondered why I got unexpected mark " highlightings in a new Vim session until I realized that I had used marks in -" a previous session and forgot to clear them. +" a previous session and forgot to clear them. " " 21-Apr-2011, Ingo Karkat " - Expose toggling of mark display (keeping the mark patterns) via new " MarkToggle mapping. Offer :MarkClear command as a replacement for the " old argumentless :Mark command, which now just disables, but not clears all -" marks. +" marks. " - Implement lazy-loading of disabled persistent marks via g:mwDoDeferredLoad -" flag passing to autoload/mark.vim. +" flag passing to autoload/mark.vim. " " 19-Apr-2011, Ingo Karkat " - ENH: Add explicit mark persistence via :MarkLoad and :MarkSave commands and " automatic persistence via the g:mwAutoLoadMarks and g:mwAutoSaveMarks -" configuration flags. +" configuration flags. " " 15-Apr-2011, Ingo Karkat " - Avoid losing the mark highlightings on :syn on or :colorscheme commands. -" Thanks to Zhou YiChao for alerting me to this issue and suggesting a fix. +" Thanks to Zhou YiChao for alerting me to this issue and suggesting a fix. " " 17-Nov-2009, Ingo Karkat " - Replaced the (overly) generic mark#GetVisualSelectionEscaped() with " mark#GetVisualSelectionAsRegexp() and -" mark#GetVisualSelectionAsLiteralPattern(). +" mark#GetVisualSelectionAsLiteralPattern(). " " 04-Jul-2009, Ingo Karkat " - A [count] before any mapping either caused "No range allowed" error or just " repeated the :call [count] times, resulting in the current search pattern " echoed [count] times and a hit-enter prompt. Now suppressing [count] via -" and handling it inside the implementation. -" - Now passing isBackward (0/1) instead of optional 'b' flag into functions. +" and handling it inside the implementation. +" - Now passing isBackward (0/1) instead of optional 'b' flag into functions. " Also passing empty regexp to mark#MarkRegex() to avoid any optional -" arguments. +" arguments. " " 02-Jul-2009, Ingo Karkat -" - Split off functions into autoload script. -" - Removed g:force_reload_mark. +" - Split off functions into autoload script. +" - Removed g:force_reload_mark. " - Initialization of global variables and autocommands is now done lazily on " the first use, not during loading of the plugin. This reduces Vim startup -" time and footprint as long as the functionality isn't yet used. +" time and footprint as long as the functionality isn't yet used. " " 6-Jun-2009, Ingo Karkat " 1. Somehow s:WrapMessage() needs a redraw before the :echo to avoid that a " later Vim redraw clears the wrap message. This happened when there's no -" statusline and thus :echo'ing into the ruler. -" 2. Removed line-continuations and ':set cpo=...'. Upper-cased and . -" 3. Added default highlighting for the special search type. +" statusline and thus :echo'ing into the ruler. +" 2. Removed line-continuations and ':set cpo=...'. Upper-cased and . +" 3. Added default highlighting for the special search type. " " 2-Jun-2009, Ingo Karkat " 1. Replaced highlighting via :syntax with matchadd() / matchdelete(). This " requires Vim 7.2 / 7.1 with patches. This method is faster, there are no " more clashes with syntax highlighting (:match always has preference), and -" the background highlighting does not disappear under 'cursorline'. -" 2. Factored :windo application out into s:MarkScope(). +" the background highlighting does not disappear under 'cursorline'. +" 2. Factored :windo application out into s:MarkScope(). " 3. Using winrestcmd() to fix effects of :windo: By entering a window, its -" height is potentially increased from 0 to 1. -" 4. Handling multiple tabs by calling s:UpdateScope() on the TabEnter event. -" +" height is potentially increased from 0 to 1. +" 4. Handling multiple tabs by calling s:UpdateScope() on the TabEnter event. +" " 1-Jun-2009, Ingo Karkat " 1. Now using Vim List for g:mwWord and thus requiring Vim 7. g:mwCycle is now -" zero-based, but the syntax groups "MarkWordx" are still one-based. -" 2. Added missing setter for re-inclusion guard. +" zero-based, but the syntax groups "MarkWordx" are still one-based. +" 2. Added missing setter for re-inclusion guard. " 3. Factored :syntax operations out of s:DoMark() and s:UpdateMark() so that -" they can all be done in a single :windo. +" they can all be done in a single :windo. " 4. Normal mode MarkSet now has the same semantics as its visual mode " cousin: If the cursor is on an existing mark, the mark is removed. " Beforehand, one could only remove a visually selected mark via again -" selecting it. Now, one simply can invoke the mapping when on such a mark. +" selecting it. Now, one simply can invoke the mapping when on such a mark. " 5. Highlighting can now actually be overridden in the vimrc (anywhere -" _before_ sourcing this script) by using ':hi def'. +" _before_ sourcing this script) by using ':hi def'. " " 31-May-2009, Ingo Karkat " 1. Refactored s:Search() to optionally take advantage of SearchSpecial.vim " autoload functionality for echoing of search pattern, wrap and error -" messages. +" messages. " 2. Now prepending search type ("any-mark", "same-mark", "new-mark") for -" better identification. +" better identification. " 3. Retired the algorithm in s:PrevWord in favor of simply using , " which makes mark.vim work like the * command. At the end of a line, " non-keyword characters may now be marked; the previous algorithm prefered -" any preceding word. +" any preceding word. " 4. BF: If 'iskeyword' contains characters that have a special meaning in a -" regex (e.g. [.*]), these are now escaped properly. +" regex (e.g. [.*]), these are now escaped properly. " " 01-Sep-2008, Ingo Karkat: bugfixes and enhancements " 1. Added MarkAllClear (without a default mapping), which clears all @@ -127,7 +141,7 @@ " continuing at TOP" and "Pattern not found:..." messages, like the * and " n/N Vim search commands. " 9. Jumps now open folds if the occurrence is inside a closed fold, just like n/N -" do. +" do. " " 10th Mar 2006, Yuheng Xie: jump to ANY mark " (*) added \* \# \/ \? for the ability of jumping to ANY mark, even when the @@ -155,7 +169,7 @@ " (*) command :Mark " -> e.g. :Mark Mark.\{-}\ze( -" Avoid installing twice or when in unsupported Vim version. +" Avoid installing twice or when in unsupported Vim version. if exists('g:loaded_mark') || (v:version == 701 && ! exists('*matchadd')) || (v:version < 701) finish endif @@ -188,20 +202,20 @@ endfunction call s:DefaultHighlightings() autocmd ColorScheme * call DefaultHighlightings() -" Default highlighting for the special search type. +" Default highlighting for the special search type. " You can override this by defining / linking the 'SearchSpecialSearchType' -" highlight group before this script is sourced. +" highlight group before this script is sourced. highlight def link SearchSpecialSearchType MoreMsg "- mappings ------------------------------------------------------------------- -nnoremap MarkSet :call mark#MarkCurrentWord() -vnoremap MarkSet :call mark#DoMark(mark#GetVisualSelectionAsLiteralPattern()) -nnoremap MarkRegex :call mark#MarkRegex('') -vnoremap MarkRegex :call mark#MarkRegex(mark#GetVisualSelectionAsRegexp()) -nnoremap MarkClear :call mark#DoMark(mark#CurrentMark()[0]) +nnoremap MarkSet :if !mark#MarkCurrentWord(v:count)execute "normal! \C-\>\C-n>\Esc>"endif +vnoremap MarkSet :if !mark#DoMark(v:count, mark#GetVisualSelectionAsLiteralPattern())execute "normal! \C-\>\C-n>\Esc>"endif +nnoremap MarkRegex :call mark#MarkRegex('') +vnoremap MarkRegex :call mark#MarkRegex(mark#GetVisualSelectionAsRegexp()) +nnoremap MarkClear :if !mark#DoMark(v:count, (v:count ? '' : mark#CurrentMark()[0]))execute "normal! \C-\>\C-n>\Esc>"endif nnoremap MarkAllClear :call mark#ClearAll() -nnoremap MarkToggle :call mark#Toggle() +nnoremap MarkToggle :call mark#Toggle() nnoremap MarkSearchCurrentNext :call mark#SearchCurrentMark(0) nnoremap MarkSearchCurrentPrev :call mark#SearchCurrentMark(1) @@ -210,7 +224,7 @@ nnoremap MarkSearchAnyPrev :call mark#SearchAnyMark(1) MarkSearchNext :if !mark#SearchNext(0)execute 'normal! *zv'endif nnoremap MarkSearchPrev :if !mark#SearchNext(1)execute 'normal! #zv'endif " When typed, [*#nN] open the fold at the search result, but inside a mapping or -" :normal this must be done explicitly via 'zv'. +" :normal this must be done explicitly via 'zv'. if !hasmapto('MarkSet', 'n') @@ -228,8 +242,8 @@ endif if !hasmapto('MarkClear', 'n') nmap n MarkClear endif -" No default mapping for MarkAllClear. -" No default mapping for MarkToggle. +" No default mapping for MarkAllClear. +" No default mapping for MarkToggle. if !hasmapto('MarkSearchCurrentNext', 'n') nmap * MarkSearchCurrentNext @@ -252,8 +266,9 @@ endif "- commands ------------------------------------------------------------------- -command! -nargs=? Mark call mark#DoMark() +command! -count -nargs=? Mark if !mark#DoMark(, ) | echoerr printf('Only %d mark highlight groups', mark#GetGroupNum()) | endif command! -bar MarkClear call mark#ClearAll() +command! -bar Marks call mark#List() command! -bar MarkLoad call mark#LoadCommand(1) command! -bar MarkSave call mark#SaveCommand() @@ -263,19 +278,19 @@ command! -bar MarkSave call mark#SaveCommand() if g:mwAutoLoadMarks " As the viminfo is only processed after sourcing of the runtime files, the " persistent global variables are not yet available here. Defer this until Vim - " startup has completed. + " startup has completed. function! s:AutoLoadMarks() if g:mwAutoLoadMarks && exists('g:MARK_MARKS') && g:MARK_MARKS !=# '[]' if ! exists('g:MARK_ENABLED') || g:MARK_ENABLED " There are persistent marks and they haven't been disabled; we need to - " show them right now. + " show them right now. call mark#LoadCommand(0) else " Though there are persistent marks, they have been disabled. We avoid " sourcing the autoload script and its invasive autocmds right now; " maybe the marks are never turned on. We just inform the autoload " script that it should do this once it is sourced on-demand by a - " mark mapping or command. + " mark mapping or command. let g:mwDoDeferredLoad = 1 endif endif @@ -285,9 +300,9 @@ if g:mwAutoLoadMarks autocmd! " Note: Avoid triggering the autoload unless there actually are persistent " marks. For that, we need to check that g:MARK_MARKS doesn't contain the - " empty list representation, and also :execute the :call. + " empty list representation, and also :execute the :call. autocmd VimEnter * call AutoLoadMarks() augroup END endif -" vim: ts=2 sw=2 +" vim: ts=4 sts=0 sw=4 noet