33" Description: Full path fuzzy file, buffer and MRU file finder for Vim.
44" Author: Kien Nguyen <github.com/kien>
55" License: MIT
6- " Version: 1.5.5
6+ " Version: 1.5.6
77" =============================================================================
88
99if v: version < ' 700' " {{{
@@ -16,6 +16,7 @@ func! s:opts()
1616 \ ' g:ctrlp_by_filename' : [' s:byfname' , 0 ],
1717 \ ' g:ctrlp_clear_cache_on_exit' : [' s:cconex' , 1 ],
1818 \ ' g:ctrlp_dotfiles' : [' s:dotfiles' , 1 ],
19+ \ ' g:ctrlp_extensions' : [' s:extensions' , []],
1920 \ ' g:ctrlp_highlight_match' : [' s:mathi' , [1 , ' Identifier' ]],
2021 \ ' g:ctrlp_jump_to_buffer' : [' s:jmptobuf' , 1 ],
2122 \ ' g:ctrlp_match_window_bottom' : [' s:mwbottom' , 1 ],
@@ -57,6 +58,12 @@ func! s:opts()
5758 let s: maxhst = g: ctrlp_max_history
5859 unl g: ctrlp_max_history
5960 endif
61+ let s: mru = g: ctrlp_mru_files
62+ if ! empty (s: extensions )
63+ for each in s: extensions
64+ exe ' ru autoload/ctrlp/' .each.' .vim'
65+ endfor
66+ endif
6067endfunc
6168cal s: opts ()
6269
@@ -74,7 +81,7 @@ endfunc
7481func ! ctrlp#clearallcaches ()
7582 let cache_dir = ctrlp#utils#cachedir ()
7683 if isdirectory (cache_dir) && match (cache_dir, ' .ctrlp_cache' ) >= 0
77- let cache_files = split (globpath (cache_dir, ' *.txt' ), ' \n' )
84+ let cache_files = split (globpath (cache_dir, ' *.txt' , 1 ), ' \n' )
7885 cal filter (cache_files, ' !isdirectory(v:val)' )
7986 for each in cache_files | sil ! cal delete (each) | endfor
8087 endif
@@ -84,7 +91,7 @@ endfunc
8491func ! ctrlp#reset ()
8592 cal s: opts ()
8693 cal ctrlp#utils#opts ()
87- if g: ctrlp_mru_files | cal ctrlp#mrufiles#opts () | endif
94+ if s: mru | cal ctrlp#mrufiles#opts () | endif
8895 " Clear user input
8996 let s: prompt = [' ' ,' ' ,' ' ]
9097 unl ! s: cline
@@ -269,18 +276,18 @@ func! s:Open(name)
269276 let s: winnr = bufwinnr (' %' )
270277 let s: bufnr = bufnr (' %' )
271278 " Store global options
272- let s: CtrlP_magic = &magic
273- let s: CtrlP_to = &to
274- let s: CtrlP_tm = &tm
275- let s: CtrlP_sb = &sb
276- let s: CtrlP_hls = &hls
277- let s: CtrlP_im = &im
278- let s: CtrlP_report = &report
279- let s: CtrlP_sc = &sc
280- let s: CtrlP_ss = &ss
281- let s: CtrlP_siso = &siso
282- let s: CtrlP_mfd = &mfd
283- let s: CtrlP_gcr = &gcr
279+ let s: glb_magic = &magic
280+ let s: glb_to = &to
281+ let s: glb_tm = &tm
282+ let s: glb_sb = &sb
283+ let s: glb_hls = &hls
284+ let s: glb_im = &im
285+ let s: glb_report = &report
286+ let s: glb_sc = &sc
287+ let s: glb_ss = &ss
288+ let s: glb_siso = &siso
289+ let s: glb_mfd = &mfd
290+ let s: glb_gcr = &gcr
284291 let s: prompt = [' ' , ' ' , ' ' ]
285292 if ! exists (' s:hstry' )
286293 let hst = filereadable (s: gethistloc ()[1 ]) ? s: gethistdata () : [' ' ]
@@ -307,18 +314,18 @@ endfunc
307314func ! s: Close ()
308315 try | bun ! | catch | clo ! | endtry
309316 " Restore global options
310- let &magic = s: CtrlP_magic
311- let &to = s: CtrlP_to
312- let &tm = s: CtrlP_tm
313- let &sb = s: CtrlP_sb
314- let &hls = s: CtrlP_hls
315- let &im = s:CtrlP_im
316- let &report = s: CtrlP_report
317- let &sc = s: CtrlP_sc
318- let &ss = s: CtrlP_ss
319- let &siso = s: CtrlP_siso
320- let &mfd = s: CtrlP_mfd
321- let &gcr = s: CtrlP_gcr
317+ let &magic = s: glb_magic
318+ let &to = s: glb_to
319+ let &tm = s: glb_tm
320+ let &sb = s: glb_sb
321+ let &hls = s: glb_hls
322+ let &im = s:glb_im
323+ let &report = s: glb_report
324+ let &sc = s: glb_sc
325+ let &ss = s: glb_ss
326+ let &siso = s: glb_siso
327+ let &mfd = s: glb_mfd
328+ let &gcr = s: glb_gcr
322329 " Cleaning up
323330 cal s: unmarksigns ()
324331 let g: ctrlp_lines = []
@@ -344,8 +351,8 @@ func! s:Renderer(lines, pat) "{{{
344351 " Output to buffer
345352 if ! empty (nls)
346353 setl cul
347- " Sort if not type 2 ( MRU)
348- if index ([ 2 ], s: itemtype) < 0
354+ " Sort if not MRU
355+ if ( s: mru && s: itemtype != 2 ) || ! s: mru
349356 let s: compat = a: pat
350357 cal sort (nls, ' s:mixedsort' )
351358 unl s: compat
@@ -650,9 +657,14 @@ func! s:PrtSelectJump(char,...)
650657endfunc
651658
652659func ! s: PrtClearCache ()
653- cal ctrlp#clearcache ()
654- cal s: SetLines (s: itemtype )
655- cal s: BuildPrompt (1 )
660+ if s: itemtype == 0
661+ cal ctrlp#clearcache ()
662+ cal s: SetLines (s: itemtype )
663+ cal s: BuildPrompt (1 )
664+ elseif s: mru && s: itemtype == 2
665+ let g: ctrlp_lines = ctrlp#mrufiles#list (-1 , 1 )
666+ cal s: BuildPrompt (1 )
667+ endif
656668endfunc
657669
658670func ! s: PrtExit ()
@@ -782,8 +794,9 @@ func! s:ToggleByFname()
782794endfunc
783795
784796func ! s: ToggleType (dir )
785- let len = 1 + g: ctrlp_mru_files
786- let s: itemtype = s: walker (len , s: itemtype , a: dir )
797+ let ext = exists (' g:ctrlp_ext_vars' ) ? len (g: ctrlp_ext_vars ) : 0
798+ let max = 1 + s: mru + ext
799+ let s: itemtype = s: walker (max , s: itemtype , a: dir )
787800 cal s: Type (s: itemtype )
788801endfunc
789802
@@ -827,12 +840,12 @@ func! ctrlp#SetWorkingPath(...)
827840 sil ! exe ' chd!' a: 1
828841 retu
829842 endif
830- if match (expand (' %:p' ), ' ^\<.\+\>://.*' ) >= 0
843+ if match (expand (' %:p' , 1 ), ' ^\<.\+\>://.*' ) >= 0
831844 \ || ! s: pathmode || ! l: pathmode
832845 retu
833846 endif
834847 if exists (' +acd' ) | let &acd = 0 | endif
835- let path = expand (' %:p:h' )
848+ let path = expand (' %:p:h' , 1 )
836849 let path = exists (' *fnameescape' ) ? fnameescape (path ) : escape (path , ' %#' )
837850 sil ! exe ' chd!' path
838851 if s: pathmode == 1 || l: pathmode == 1 | retu | endif
@@ -849,35 +862,16 @@ func! ctrlp#SetWorkingPath(...)
849862 endif
850863 for marker in markers
851864 let found = s: FindRoot (getcwd (), marker, 0 , 0 )
852- if getcwd () != expand (' %:p:h' ) || found | break | endif
865+ if getcwd () != expand (' %:p:h' , 1 ) || found | break | endif
853866 endfor
854867endfunc
855868" }}}
856869
857- func ! s: AcceptSelection (mode ,... ) " {{{
858- let [md, prt] = [a: mode , s: prompt ]
859- let str = prt[0 ] . prt[1 ] . prt[2 ]
860- if md == ' e' && ! s: itemtype
861- if str == ' ..'
862- " Walk backward the dir tree
863- cal s: parentdir (getcwd ())
864- cal s: SetLines (s: itemtype )
865- cal s: PrtClear ()
866- retu
867- elseif str == ' ?'
868- " Use ? for help
869- cal s: PrtExit ()
870- let hlpwin = &columns > 159 ? ' | vert res 80' : ' '
871- exe ' bo vert h ctrlp-mappings' hlpwin ' | norm! 0'
872- retu
873- endif
874- endif
870+ " * AcceptSelection {{{
871+ func ! ctrlp#acceptfile (mode , matchstr )
872+ let [md, matchstr ] = [a: mode , a: matchstr ]
875873 " Get the full path
876- let matchstr = matchstr (getline (' .' ), ' ^> \zs.\+\ze\t*$' )
877- if empty (matchstr ) | retu | endif
878874 let filpath = s: itemtype ? matchstr : getcwd ().s: lash .matchstr
879- " If only need the full path
880- if exists (' a:1' ) && a: 1 | retu filpath | endif
881875 cal s: PrtExit ()
882876 let bufnum = bufnr (filpath)
883877 let norwins = s: normbuf ()
@@ -894,7 +888,6 @@ func! s:AcceptSelection(mode,...) "{{{
894888 endif
895889 " Switch to existing buffer or open new one
896890 let filpath = escape (filpath, ' %#' )
897- " If the file's already opened
898891 if exists (' jmpb' ) && buftab[0 ] " In a tab
899892 exe ' norm!' buftab[1 ].' gt'
900893 exe buftab[0 ].' winc w'
@@ -909,7 +902,7 @@ func! s:AcceptSelection(mode,...) "{{{
909902 let cmd = ' new'
910903 elseif md == ' v' || s: splitwin == 3 " In new ver split
911904 let cmd = ' vne'
912- elseif md == ' e '
905+ else
913906 let cmd = ' e'
914907 " If there's at least 1 normal buffer
915908 if norwin
@@ -930,8 +923,41 @@ func! s:AcceptSelection(mode,...) "{{{
930923 if ! empty (' tail' )
931924 sil ! norm! zOzz
932925 endif
926+ endfunc
927+
928+ func ! s: AcceptSelection (mode )
929+ if a: mode == ' e'
930+ let prt = s: prompt
931+ let str = prt[0 ] . prt[1 ] . prt[2 ]
932+ if str == ' ..' && ! s: itemtype
933+ " Walk backward the dir tree
934+ cal s: parentdir (getcwd ())
935+ cal s: SetLines (s: itemtype )
936+ cal s: PrtClear ()
937+ retu
938+ elseif str == ' ?'
939+ " Use ? for help
940+ cal s: PrtExit ()
941+ let hlpwin = &columns > 159 ? ' | vert res 80' : ' '
942+ sil ! exe ' bo vert h ctrlp-mappings' hlpwin ' | norm! 0'
943+ retu
944+ endif
945+ endif
946+ " Get the selected line
947+ let matchstr = matchstr (getline (' .' ), ' ^> \zs.\+\ze\t*$' )
948+ if empty (matchstr ) | retu | endif
949+ " Branch it
950+ let rhs = s: mru ? ' 0\|1\|2' : ' 0\|1'
951+ if s: itemtype = ~ rhs
952+ cal ctrlp#acceptfile (a: mode , matchstr )
953+ else
954+ let id = s: itemtype - 2 - s: mru
955+ let acpt_func = g: ctrlp_ext_vars [id][1 ]
956+ cal call (acpt_func, [a: mode , matchstr ])
957+ endif
933958 ec
934- endfunc " }}}
959+ endfunc
960+ " }}}
935961
936962" ** Helper functions {{{
937963" Sorting {{{
@@ -969,12 +995,11 @@ func! s:matchlens(str, pat, ...)
969995 let lens = exists (' a:2' ) ? a: 2 : {}
970996 let nr = exists (' a:3' ) ? a: 3 : 0
971997 if match (a: str , a: pat , st ) != -1
972- let start = match (a: str , a: pat , st )
973- let str = matchstr (a: str , a: pat , st )
974- let len = len (str)
975- let end = matchend (a: str , a: pat , st )
976- let lens = extend (lens, { nr : [len , str] })
977- let lens = s: matchlens (a: str , a: pat , end , lens, nr + 1 )
998+ let str = matchstr (a: str , a: pat , st )
999+ let len = len (str)
1000+ let end = matchend (a: str , a: pat , st )
1001+ let lens = extend (lens, { nr : [len , str] })
1002+ let lens = s: matchlens (a: str , a: pat , end , lens, nr + 1 )
9781003 endif
9791004 retu lens
9801005endfunc
@@ -988,7 +1013,7 @@ func! s:shortest(lens)
9881013endfunc
9891014
9901015func ! s: wordonly (lens)
991- let lens = a: lens
1016+ let lens = a: lens
9921017 let minln = s: shortest (lens)
9931018 cal filter (lens, ' minln == v:val[0]' )
9941019 for nr in keys (lens)
@@ -999,27 +1024,38 @@ endfunc
9991024
10001025func ! s: mixedsort (s1, s2)
10011026 let cmatlen = s: compmatlen (a: s1 , a: s2 )
1002- let ctime = s: comptime (a: s1 , a: s2 )
1003- let clen = s: complen (a: s1 , a: s2 )
1004- let cword = s: compword (a: s1 , a: s2 )
1005- retu 3 * cmatlen + 3 * ctime + 2 * clen + cword
1027+ let clen = s: complen (a: s1 , a: s2 )
1028+ let rhs = s: mru ? ' 0\|1\|2' : ' 0\|1'
1029+ if s: itemtype = ~ rhs
1030+ let ctime = s: comptime (a: s1 , a: s2 )
1031+ let cword = s: compword (a: s1 , a: s2 )
1032+ let mxsrt = 6 * cmatlen + 3 * ctime + 2 * clen + cword
1033+ else
1034+ let mxsrt = 2 * cmatlen + clen
1035+ endif
1036+ retu mxsrt
10061037endfunc
10071038" }}}
10081039
10091040" Statusline {{{
10101041func ! s: statusline (... )
1011- let itemtypes = [
1042+ let types = [
10121043 \ [' files' , ' fil' ],
10131044 \ [' buffers' , ' buf' ],
10141045 \ [' mru files' , ' mru' ],
10151046 \ ]
1016- if ! g: ctrlp_mru_files
1017- cal remove (itemtypes , 2 )
1047+ if ! s: mru
1048+ cal remove (types , 2 )
10181049 endif
1019- let max = len (itemtypes) - 1
1020- let next = itemtypes[s: walker (max , s: itemtype , 1 , 1 )][1 ]
1021- let prev = itemtypes[s: walker (max , s: itemtype , -1 , 1 )][1 ]
1022- let item = itemtypes[s: itemtype ][0 ]
1050+ if exists (' g:ctrlp_ext_vars' )
1051+ for each in g: ctrlp_ext_vars
1052+ cal add (types, [ each[2 ], each[3 ] ])
1053+ endfor
1054+ endif
1055+ let max = len (types) - 1
1056+ let next = types[s: walker (max , s: itemtype , 1 )][1 ]
1057+ let prev = types[s: walker (max , s: itemtype , -1 )][1 ]
1058+ let item = types[s: itemtype ][0 ]
10231059 let focus = s: Focus () ? ' prt' : ' win'
10241060 let byfname = s: byfname ? ' file' : ' path'
10251061 let regex = s: regexp ? ' %#LineNr# regex %*' : ' '
@@ -1077,7 +1113,7 @@ endfunc
10771113
10781114func ! s: listdirs (path ,parent)
10791115 let str = ' '
1080- for entry in filter (split (globpath (a: path , ' *' ), ' \n' ), ' isdirectory(v:val)' )
1116+ for entry in filter (split (globpath (a: path , ' *' , 1 ), ' \n' ), ' isdirectory(v:val)' )
10811117 let str .= a: parent .split (entry, ' [\/]' )[-1 ] . " \n "
10821118 endfor
10831119 retu str
@@ -1241,6 +1277,10 @@ endfunc
12411277" }}}
12421278
12431279" Misc {{{
1280+ func ! ctrlp#exit ()
1281+ cal s: PrtExit ()
1282+ endfunc
1283+
12441284func ! s: openfile (cmd)
12451285 try
12461286 exe a: cmd
@@ -1251,16 +1291,12 @@ func! s:openfile(cmd)
12511291 endtry
12521292endfunc
12531293
1254- func ! s: walker (max , pos, dir , ... )
1255- if a: dir == 1
1294+ func ! s: walker (max , pos, dir )
1295+ if a: dir > 0
12561296 let pos = a: pos < a: max ? a: pos + 1 : 0
1257- elseif a: dir == -1
1297+ else
12581298 let pos = a: pos > 0 ? a: pos - 1 : a: max
12591299 endif
1260- if ! g: ctrlp_mru_files && pos == 2 && ! exists (' a:1' )
1261- let jmp = pos == a: max ? 0 : 3
1262- let pos = a: pos == 1 ? jmp : 1
1263- endif
12641300 retu pos
12651301endfunc
12661302
@@ -1336,6 +1372,14 @@ func! s:SetLines(type)
13361372 \ ' s:ListAllBuffers()' ,
13371373 \ ' ctrlp#mrufiles#list(-1)' ,
13381374 \ ]
1375+ if ! s: mru
1376+ cal remove (types, 2 )
1377+ endif
1378+ if exists (' g:ctrlp_ext_vars' )
1379+ for each in g: ctrlp_ext_vars
1380+ cal add (types, each[0 ])
1381+ endfor
1382+ endif
13391383 let g: ctrlp_lines = eval (types[a: type ])
13401384endfunc
13411385
0 commit comments