Skip to content

Commit 0319703

Browse files
committed
Support user extensions
* Search for and perform actions on anything you want, not just files, buffers and MRU. Check out the 'extensions' branch for more details and how-to. * <F5> now also removes deleted files from MRU list. * Slight sorting change.
1 parent b44a699 commit 0319703

File tree

5 files changed

+175
-110
lines changed

5 files changed

+175
-110
lines changed

autoload/ctrlp.vim

Lines changed: 132 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
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

99
if 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
6067
endfunc
6168
cal s:opts()
6269

@@ -74,7 +81,7 @@ endfunc
7481
func! 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
8491
func! 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
307314
func! 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,...)
650657
endfunc
651658

652659
func! 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
656668
endfunc
657669

658670
func! s:PrtExit()
@@ -782,8 +794,9 @@ func! s:ToggleByFname()
782794
endfunc
783795

784796
func! 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)
788801
endfunc
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
854867
endfunc
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
9801005
endfunc
@@ -988,7 +1013,7 @@ func! s:shortest(lens)
9881013
endfunc
9891014

9901015
func! 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

10001025
func! 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
10061037
endfunc
10071038
"}}}
10081039

10091040
" Statusline {{{
10101041
func! 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

10781114
func! 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+
12441284
func! s:openfile(cmd)
12451285
try
12461286
exe a:cmd
@@ -1251,16 +1291,12 @@ func! s:openfile(cmd)
12511291
endtry
12521292
endfunc
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
12651301
endfunc
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])
13401384
endfunc
13411385

0 commit comments

Comments
 (0)