diff --git a/autoload/ctrlp.vim b/autoload/ctrlp.vim index 5969793b..309b5f09 100644 --- a/autoload/ctrlp.vim +++ b/autoload/ctrlp.vim @@ -136,6 +136,7 @@ let [s:lcmap, s:prtmaps] = ['nn ', { \ 'AcceptSelection("t")': [''], \ 'AcceptSelection("v")': ['', ''], \ 'ToggleFocus()': [''], + \ 'PrtInputItem()': [''], \ 'ToggleRegex()': [''], \ 'ToggleByFname()': [''], \ 'ToggleType(1)': ['', ''], @@ -1137,6 +1138,14 @@ fu! s:ToggleFocus() let s:focus = !s:focus cal s:BuildPrompt(0) endf +function! s:PrtInputItem() + " I don't know how to remeber old mappings + cmap + let oldText = s:prompt[0] + let str = input(oldText . ' ') + call s:PrtAdd((len(oldText) ? ' ' : '') . str) + cunmap +endfunction fu! s:ToggleRegex() let s:regexp = !s:regexp @@ -1988,9 +1997,11 @@ fu! ctrlp#syntax() endf fu! s:highlight(pat, grp) - if s:matcher != {} | retu | en + if s:matcher != {} && !has_key(s:matcher, 'highlight')| retu | en cal clearmatches() - if !empty(a:pat) && s:ispath + if !empty(a:pat) && s:matcher != {} " user-defined highlights + call call(s:matcher['highlight'], [a:pat, a:grp]) + elseif !empty(a:pat) && s:ispath if s:regexp let pat = substitute(a:pat, '\\\@ \\zs', 'g') cal matchadd(a:grp, ( s:martcs == '' ? '\c' : '\C' ).pat) diff --git a/autoload/ctrlp/buffilter.vim b/autoload/ctrlp/buffilter.vim new file mode 100644 index 00000000..f464f99e --- /dev/null +++ b/autoload/ctrlp/buffilter.vim @@ -0,0 +1,104 @@ +" ============================================================================= +" File: autoload/ctrlp/buffilter.vim +" Description: BufFilter extension +" modified based on CtrlPLine +" Author: Troy Daniel +" ============================================================================= + +" Init {{{1 +if exists('g:loaded_ctrlp_buffilter') && g:loaded_ctrlp_buffilter + fini +en +let g:loaded_ctrlp_buffilter = 1 + +cal add(g:ctrlp_ext_vars, { + \ 'init': 'ctrlp#buffilter#init(s:crbufnr)', + \ 'accept': 'ctrlp#buffilter#accept', + \ 'exit': 'ctrlp#buffilter#exit()', + \ 'lname': 'lines', + \ 'sname': 'lns', + \ 'sort': 0, + \ 'type': 'tabe', + \ }) + +let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars) +" Utilities {{{1 +fu! s:syntax() + if !ctrlp#nosy() + cal ctrlp#hicheck('CtrlPBufName', 'Directory') + cal ctrlp#hicheck('CtrlPTabExtra', 'Comment') + sy match CtrlPBufName '\t|\zs[^|]\+\ze|\d\+:\d\+|$' + sy match CtrlPTabExtra '\zs\t.*\ze$' contains=CtrlPBufName + highlight link CtrlPMatch DiffChange + en +endf +" Public {{{1 +" use buffilter only in buffilter mode +fu! ctrlp#buffilter#exit() + unlet g:ctrlp_match_func +endf + +fu! ctrlp#buffilter#init(bufnr) + let [lines, bufnr] = [[], a:bufnr] + let bufs = exists('s:lnmode') && s:lnmode ? ctrlp#buffers('id') : [bufnr] + " Load only the current buffer + let [lfb, bufn] = [getbufline(bufnr, 1, '$'), bufname(bufnr)] + if lfb == [] && bufn != '' + let lfb = ctrlp#utils#readfile(fnamemodify(bufn, ':p')) + en + cal map(lfb, 'tr(v:val, '' '', '' '')') + let [linenr, len_lfb] = [1, len(lfb)] + let buft = bufn == '' ? '[No Name]' : fnamemodify(bufn, ':t') + wh linenr <= len_lfb + let lfb[linenr - 1] .= ' |'.buft.'|'.bufnr.':'.linenr.'|' + let linenr += 1 + endw + cal extend(lines, filter(lfb, 'v:val !~ ''^\s*\t|[^|]\+|\d\+:\d\+|$''')) + cal s:syntax() + retu lines +endf + +fu! ctrlp#buffilter#accept(mode, str) + let info = matchlist(a:str, '\t|[^|]\+|\(\d\+\):\(\d\+\)|$') + let bufnr = str2nr(get(info, 1)) + if bufnr + cal ctrlp#acceptfile('Et', bufnr, get(info, 2)) " jump to buffer, + " cal ctrlp#acceptfile(a:mode, bufnr, get(info, 2)) + en +endf + +fu! ctrlp#buffilter#cmd(mode, ...) + let s:lnmode = a:mode + if a:0 && !empty(a:1) + let s:lnmode = 0 + let bname = a:1 =~# '^%$\|^#\d*$' ? expand(a:1) : a:1 + let s:bufnr = bufnr('^'.fnamemodify(bname, ':p').'$') + en + + let g:ctrlp_match_func = { 'match': "ctrlp#buffilter#matcher", + \ "highlight": 'ctrlp#buffilter#patterner'} + " let g:ctrlp_pattern_func = [1, 'ctrlp#buffilter#patterner'] + retu s:id +endf +"}}} + +function! ctrlp#buffilter#patterner(str, grp) + echom "ctrlp#buffilter#patterner: " . a:str + let patterns=split(tolower(a:str), '\s\+', 0) + let searchPattern = join(map(patterns, 'SearchEscape(v:val)'), '\|') + cal matchadd(a:grp, searchPattern) + " return searchPattern +endfunction + +function! ctrlp#buffilter#matcher(items, str, limit, mmode, ispath, crfile, regex) + echo "ctrlp#buffilter#matcher" + let items=copy(a:items) + let patterns=split(tolower(a:str), '\s\+', 0) + for p in patterns + call filter(items, 'stridx(tolower(v:val), p) >=0 ') + endfor + echo []+items + return []+items +endfunction + +" vim:fen:fdm=marker:fmr={{{,}}}:fdl=0:fdc=1:ts=2:sw=2:sts=2 diff --git a/doc/ctrlp.txt b/doc/ctrlp.txt index 82eecfcb..0b62beb8 100644 --- a/doc/ctrlp.txt +++ b/doc/ctrlp.txt @@ -1213,6 +1213,18 @@ Available extensions:~ - Name: 'line' - Command: ":CtrlPLine [buffer]" - Search for a line in all listed buffers or in the specified [buffer]. + + *:CtrlPBufFilter* + * BufFilter mode: ~ + - Name: 'buffilter' + - Command: ":CtrlPBufFilter" + - This mode is quite different to the Line mode. In this mode, you can type + a few keywords splitted by space, then only the lines contains all the + keywords will show up. No fuzzy search. + In addition, you can press , and then you'll be prompt for + keywods, after type the keywords, you can type again (or + of coursr)to return to the filter mode. This mode is speically useful for + those who need non-ascii input, or paste from keyboard. *:CtrlPChange* *:CtrlPChangeAll* diff --git a/plugin/ctrlp.vim b/plugin/ctrlp.vim index 1e56ecaf..dd14fad8 100644 --- a/plugin/ctrlp.vim +++ b/plugin/ctrlp.vim @@ -59,6 +59,8 @@ com! -bar CtrlPUndo cal ctrlp#init(ctrlp#undo#id()) com! -n=? -com=buffer CtrlPLine \ cal ctrlp#init(ctrlp#line#cmd('buf', )) +com! -n=? -com=buffer CtrlPBufFilter + \ cal ctrlp#init(ctrlp#buffilter#cmd(1, )) com! -n=? -com=buffer CtrlPChange \ cal ctrlp#init(ctrlp#changes#cmd('fil', ))