Enhancements for prompt history and :CtrlP [start-dir]

Can now use <tab> to auto-complete the directory for the :CtrlP [starting-directory] command.
Prompt history: put last string into history as well (accepted or not).
Remove |g:ctrlp_persistent_input|, |g:ctrlp_live_update| and <c-^>.
This commit is contained in:
Kien N 2011-10-07 21:10:14 +07:00
parent 1a2c3ee8d2
commit c8d02c5902
5 changed files with 245 additions and 231 deletions

View File

@ -3,7 +3,7 @@
" Description: Full path fuzzy file, buffer and MRU file finder for Vim. " Description: Full path fuzzy file, buffer and MRU file finder for Vim.
" Author: Kien Nguyen <github.com/kien> " Author: Kien Nguyen <github.com/kien>
" License: MIT " License: MIT
" Version: 1.5 " Version: 1.5.1
" ============================================================================= " =============================================================================
if v:version < '700' "{{{ if v:version < '700' "{{{
@ -14,7 +14,6 @@ endif "}}}
func! s:opts() func! s:opts()
let opts = { let opts = {
\ 'g:ctrlp_match_window_reversed' : ['s:mwreverse', 1], \ 'g:ctrlp_match_window_reversed' : ['s:mwreverse', 1],
\ 'g:ctrlp_persistent_input' : ['s:pinput', 0],
\ 'g:ctrlp_split_window' : ['s:splitwin', 0], \ 'g:ctrlp_split_window' : ['s:splitwin', 0],
\ 'g:ctrlp_working_path_mode' : ['s:pathmode', 1], \ 'g:ctrlp_working_path_mode' : ['s:pathmode', 1],
\ 'g:ctrlp_root_markers' : ['s:rmarkers', []], \ 'g:ctrlp_root_markers' : ['s:rmarkers', []],
@ -25,20 +24,15 @@ func! s:opts()
\ 'g:ctrlp_by_filename' : ['s:byfname', 0], \ 'g:ctrlp_by_filename' : ['s:byfname', 0],
\ 'g:ctrlp_prompt_mappings' : ['s:urprtmaps', 0], \ 'g:ctrlp_prompt_mappings' : ['s:urprtmaps', 0],
\ 'g:ctrlp_dotfiles' : ['s:dotfiles', 1], \ 'g:ctrlp_dotfiles' : ['s:dotfiles', 1],
\ 'g:ctrlp_highlight_match' : ['s:mathi', [1, 'Function']], \ 'g:ctrlp_highlight_match' : ['s:mathi', [1, 'Identifier']],
\ 'g:ctrlp_max_files' : ['s:maxfiles', 20000], \ 'g:ctrlp_max_files' : ['s:maxfiles', 20000],
\ 'g:ctrlp_max_depth' : ['s:maxdepth', 40], \ 'g:ctrlp_max_depth' : ['s:maxdepth', 40],
\ 'g:ctrlp_live_update' : ['s:liup', 1],
\ 'g:ctrlp_open_new_file' : ['s:newfop', 3], \ 'g:ctrlp_open_new_file' : ['s:newfop', 3],
\ 'g:ctrlp_open_multi' : ['s:opmul', 1], \ 'g:ctrlp_open_multi' : ['s:opmul', 1],
\ } \ }
for key in keys(opts) for key in keys(opts)
if call('exists', [key]) let def = call('exists', [key]) ? string(eval(key)) : string(opts[key][1])
let def = type(eval(key)) != 1 ? string(eval(key)) : eval(key) exe 'unl!' key
exe 'unl' key
else
let def = type(opts[key][1]) != 1 ? string(opts[key][1]) : opts[key][1]
endif
exe 'let' opts[key][0] '=' def exe 'let' opts[key][0] '=' def
endfor endfor
if !exists('g:ctrlp_cache_dir') if !exists('g:ctrlp_cache_dir')
@ -253,33 +247,19 @@ func! s:GetMatchedItems(items, pats, limit)
let newitems = s:MatchIt(items, each, limit) let newitems = s:MatchIt(items, each, limit)
endif endif
endfor endfor
let s:nomatches = len(newitems) let s:matches = len(newitems)
retu newitems retu newitems
endfunc endfunc
"}}} "}}}
func! s:SetupBlank() "{{{
setl bt=nofile bh=unload noswf nobl ts=4 sw=4 sts=4 nonu
\ nowrap nolist nospell cul nocuc tw=0 wfh
if v:version >= '703'
setl nornu noudf cc=0
endif
redr
endfunc "}}}
func! s:BufOpen(...) "{{{ func! s:BufOpen(...) "{{{
" a:1 bufname; a:2 delete if exists('a:2')
let buf = a:1 " Closing
" Closing, use s:winnr as a switch to avoid an issue with Vim 7.2
if exists('s:winnr')
try try
bun! bun!
catch catch
winc c winc c
endtry endtry
unl! s:winnr
endif
if exists('a:2')
exe s:currwin.'winc w' exe s:currwin.'winc w'
" Restore the changed global options " Restore the changed global options
let &magic = s:CtrlP_magic let &magic = s:CtrlP_magic
@ -298,19 +278,21 @@ func! s:BufOpen(...) "{{{
cal s:unmarksigns() cal s:unmarksigns()
let g:ctrlp_lines = [] let g:ctrlp_lines = []
let g:ctrlp_allfiles = [] let g:ctrlp_allfiles = []
if s:pinput != 2 unl! g:CtrlP_cline
unl! g:CtrlP_cline
endif
if exists('s:cwd') if exists('s:cwd')
exe 'chd!' s:cwd exe 'chd!' s:cwd
unl s:cwd unl s:cwd
endif endif
unl! s:focus s:firstinit s:hisidx s:hstgot s:marked s:bufnr unl! s:focus s:hisidx s:hstgot s:marked s:winnr s:init
" Record the input string
let prt = g:CtrlP_prompt
cal s:recordhist(prt[0] . prt[1] . prt[2])
ec ec
else else
let s:currwin = winnr() let s:currwin = winnr()
" Open new buffer " Open new buffer
exe 'sil! bo 1new' buf sil! exe 'bo 1new' a:1
abc <buffer>
let s:winnr = bufwinnr('%') let s:winnr = bufwinnr('%')
let s:bufnr = bufnr('%') let s:bufnr = bufnr('%')
" Store global options " Store global options
@ -326,9 +308,7 @@ func! s:BufOpen(...) "{{{
let s:CtrlP_siso = &siso let s:CtrlP_siso = &siso
let s:CtrlP_gcr = &gcr let s:CtrlP_gcr = &gcr
let s:CtrlP_mfd = &mfd let s:CtrlP_mfd = &mfd
if !s:pinput let g:CtrlP_prompt = ['', '', '']
let g:CtrlP_prompt = ['', '', '']
endif
if !exists('s:hstry') if !exists('s:hstry')
let hst = filereadable(s:gethistloc()[1]) ? s:gethistdata() : [''] let hst = filereadable(s:gethistloc()[1]) ? s:gethistdata() : ['']
let s:hstry = empty(hst) || !s:maxhst ? [''] : hst let s:hstry = empty(hst) || !s:maxhst ? [''] : hst
@ -353,10 +333,7 @@ endfunc "}}}
func! s:Renderer(lines, pat) "{{{ func! s:Renderer(lines, pat) "{{{
cal s:unmarksigns() cal s:unmarksigns()
let nls = [] let nls = deepcopy(a:lines)
for i in range(0, len(a:lines) - 1)
cal add(nls, '> '.a:lines[i])
endfor
" Determine/set max height " Determine/set max height
let height = s:mxheight let height = s:mxheight
let max = len(nls) < height ? len(nls) : height let max = len(nls) < height ? len(nls) : height
@ -373,6 +350,8 @@ func! s:Renderer(lines, pat) "{{{
if s:mwreverse if s:mwreverse
cal reverse(nls) cal reverse(nls)
endif endif
let s:matched = deepcopy(nls)
cal map(nls, 'substitute(v:val, "^", "> ", "")')
cal setline('1', nls) cal setline('1', nls)
if s:mwreverse if s:mwreverse
keepj norm! G keepj norm! G
@ -380,8 +359,7 @@ func! s:Renderer(lines, pat) "{{{
keepj norm! gg keepj norm! gg
endif endif
keepj norm! 1| keepj norm! 1|
let s:matched = nls cal s:remarksigns(s:matched)
cal s:remarksigns(nls)
else else
setl nocul setl nocul
cal setline('1', ' == NO MATCHES ==') cal setline('1', ' == NO MATCHES ==')
@ -406,7 +384,7 @@ func! s:UpdateMatches(pat) "{{{
endif endif
endfunc "}}} endfunc "}}}
func! s:BuildPrompt(...) "{{{ func! s:BuildPrompt(upd,...) "{{{
let base1 = s:regexp ? 'r' : '>' let base1 = s:regexp ? 'r' : '>'
let base2 = s:byfname ? 'd' : '>' let base2 = s:byfname ? 'd' : '>'
let base = base1.base2.'> ' let base = base1.base2.'> '
@ -415,16 +393,17 @@ func! s:BuildPrompt(...) "{{{
let prt = deepcopy(g:CtrlP_prompt) let prt = deepcopy(g:CtrlP_prompt)
cal map(prt, 'escape(v:val, estr)') cal map(prt, 'escape(v:val, estr)')
let str = prt[0] . prt[1] . prt[2] let str = prt[0] . prt[1] . prt[2]
if s:nomatches && ( s:liup || s:firstinit ) if ( s:matches || s:regexp || match(str, '[*|]') >= 0 ) && a:upd
let s:firstinit = 0
sil! cal s:UpdateMatches(str) sil! cal s:UpdateMatches(str)
endif endif
sil! cal s:statusline() sil! cal s:statusline()
" Toggling " Toggling
if !exists('a:1') || ( exists('a:1') && a:1 ) if !exists('a:1') || ( exists('a:1') && a:1 )
let hiactive = 'Normal' let hiactive = 'Normal'
let hicursor = 'Constant'
elseif exists('a:1') || ( exists('a:1') && !a:1 ) elseif exists('a:1') || ( exists('a:1') && !a:1 )
let hiactive = 'Comment' let hiactive = 'Comment'
let hicursor = 'Comment'
let base = substitute(base, '>', '-', 'g') let base = substitute(base, '>', '-', 'g')
endif endif
let hibase = 'Comment' let hibase = 'Comment'
@ -432,7 +411,7 @@ func! s:BuildPrompt(...) "{{{
redr redr
exe 'echoh' hibase '| echon "'.base.'" exe 'echoh' hibase '| echon "'.base.'"
\ | echoh' hiactive '| echon "'.prt[0].'" \ | echoh' hiactive '| echon "'.prt[0].'"
\ | echoh' hibase '| echon "'.prt[1].'" \ | echoh' hicursor '| echon "'.prt[1].'"
\ | echoh' hiactive '| echon "'.prt[2].'" \ | echoh' hiactive '| echon "'.prt[2].'"
\ | echoh None' \ | echoh None'
" Append the cursor _ at the end " Append the cursor _ at the end
@ -441,14 +420,6 @@ func! s:BuildPrompt(...) "{{{
endif endif
endfunc "}}} endfunc "}}}
func! s:ForceUpdate() "{{{
let estr = '"\'
let prt = deepcopy(g:CtrlP_prompt)
cal map(prt, 'escape(v:val, estr)')
let str = prt[0] . prt[1] . prt[2]
cal s:UpdateMatches(str)
endfunc "}}}
func! s:CreateNewFile() "{{{ func! s:CreateNewFile() "{{{
let prt = g:CtrlP_prompt let prt = g:CtrlP_prompt
let str = prt[0] . prt[1] . prt[2] let str = prt[0] . prt[1] . prt[2]
@ -456,7 +427,6 @@ func! s:CreateNewFile() "{{{
let arr = split(str, '[\/]') let arr = split(str, '[\/]')
cal map(arr, 'escape(v:val, "%#")') cal map(arr, 'escape(v:val, "%#")')
let fname = remove(arr, -1) let fname = remove(arr, -1)
cal s:recordhist(str)
winc c winc c
if s:newfop == 1 " In new tab if s:newfop == 1 " In new tab
tabnew tabnew
@ -470,10 +440,10 @@ func! s:CreateNewFile() "{{{
endif endif
if len(arr) if len(arr)
if isdirectory(s:createparentdirs(arr)) if isdirectory(s:createparentdirs(arr))
exe 'bo '.cmd.' '.str sil! exe 'bo '.cmd.' '.str
endif endif
else else
exe 'bo '.cmd.' '.fname sil! exe 'bo '.cmd.' '.fname
endif endif
cal s:insertcache(str) cal s:insertcache(str)
endfunc "}}} endfunc "}}}
@ -510,12 +480,15 @@ func! s:MarkToOpen()
endfunc endfunc
func! s:OpenMulti() func! s:OpenMulti()
if !exists('s:marked') || !s:opmul | retu | endif if !exists('s:marked') || !s:opmul
cal s:AcceptSelection('e')
retu
endif
let marked = deepcopy(s:marked) let marked = deepcopy(s:marked)
let prt = g:CtrlP_prompt let prt = g:CtrlP_prompt
let str = prt[0] . prt[1] . prt[2] let str = prt[0] . prt[1] . prt[2]
if !empty(str) | cal s:recordhist(str) | endif
if !has('autocmd') | cal s:BufOpen('ControlP', 'del') | endif if !has('autocmd') | cal s:BufOpen('ControlP', 'del') | endif
exe s:currwin.'winc w'
" Try not to open in new tab " Try not to open in new tab
let bufs = [] let bufs = []
for winnr in range(1, winnr('$')) for winnr in range(1, winnr('$'))
@ -523,7 +496,7 @@ func! s:OpenMulti()
endfor endfor
let ntab = 1 let ntab = 1
" Check if the other window only has a blank buffer " Check if the other window only has a blank buffer
if len(bufs) == 2 if len(bufs) == 1
for each in bufs for each in bufs
if getbufvar(each, '&bl') && empty(bufname(each)) if getbufvar(each, '&bl') && empty(bufname(each))
\ && empty(getbufvar(each, '&bt')) && empty(getbufvar(each, '&ft')) \ && empty(getbufvar(each, '&bt')) && empty(getbufvar(each, '&ft'))
@ -537,50 +510,48 @@ func! s:OpenMulti()
let ic = 1 let ic = 1
for key in keys(marked) for key in keys(marked)
let filpath = marked[key] let filpath = marked[key]
exe 'bo vne' filpath sil! exe 'bo vne' filpath
if s:opmul > 1 && s:opmul < ic if s:opmul > 1 && s:opmul < ic
winc c winc c
else else
let ic += 1 let ic += 1
endif endif
endfor endfor
if ntab 1winc w | winc c
1winc w | winc c
endif
ec ec
endfunc endfunc
"}}} "}}}
" * Prt Actions {{{ " * Prt Actions {{{
func! s:PrtClear() func! s:PrtClear()
let s:nomatches = 1 let s:matches = 1
unl! s:hstgot unl! s:hstgot
let g:CtrlP_prompt = ['','',''] let g:CtrlP_prompt = ['','','']
cal s:BuildPrompt() cal s:BuildPrompt(1)
endfunc endfunc
func! s:PrtAdd(char) func! s:PrtAdd(char)
unl! s:hstgot unl! s:hstgot
let prt = g:CtrlP_prompt let prt = g:CtrlP_prompt
let prt[0] = prt[0] . a:char let prt[0] = prt[0] . a:char
cal s:BuildPrompt() cal s:BuildPrompt(1)
endfunc endfunc
func! s:PrtBS() func! s:PrtBS()
let s:nomatches = 1 let s:matches = 1
unl! s:hstgot unl! s:hstgot
let prt = g:CtrlP_prompt let prt = g:CtrlP_prompt
let prt[0] = strpart(prt[0], -1, strlen(prt[0])) let prt[0] = strpart(prt[0], -1, strlen(prt[0]))
cal s:BuildPrompt() cal s:BuildPrompt(1)
endfunc endfunc
func! s:PrtDelete() func! s:PrtDelete()
let s:nomatches = 1 let s:matches = 1
unl! s:hstgot unl! s:hstgot
let prt = g:CtrlP_prompt let prt = g:CtrlP_prompt
let prt[1] = strpart(prt[2], 0, 1) let prt[1] = strpart(prt[2], 0, 1)
let prt[2] = strpart(prt[2], 1) let prt[2] = strpart(prt[2], 1)
cal s:BuildPrompt() cal s:BuildPrompt(1)
endfunc endfunc
func! s:PrtCurLeft() func! s:PrtCurLeft()
@ -590,13 +561,15 @@ func! s:PrtCurLeft()
let prt[1] = strpart(prt[0], strlen(prt[0]) - 1) let prt[1] = strpart(prt[0], strlen(prt[0]) - 1)
let prt[0] = strpart(prt[0], -1, strlen(prt[0])) let prt[0] = strpart(prt[0], -1, strlen(prt[0]))
endif endif
cal s:BuildPrompt() cal s:BuildPrompt(0)
endfunc endfunc
func! s:PrtCurRight() func! s:PrtCurRight()
let prt = g:CtrlP_prompt let prt = g:CtrlP_prompt
let prt[0] = prt[0] . prt[1] let prt[0] = prt[0] . prt[1]
cal s:PrtDelete() let prt[1] = strpart(prt[2], 0, 1)
let prt[2] = strpart(prt[2], 1)
cal s:BuildPrompt(0)
endfunc endfunc
func! s:PrtCurStart() func! s:PrtCurStart()
@ -605,7 +578,7 @@ func! s:PrtCurStart()
let prt[2] = strpart(str, 1) let prt[2] = strpart(str, 1)
let prt[1] = strpart(str, 0, 1) let prt[1] = strpart(str, 0, 1)
let prt[0] = '' let prt[0] = ''
cal s:BuildPrompt() cal s:BuildPrompt(0)
endfunc endfunc
func! s:PrtCurEnd() func! s:PrtCurEnd()
@ -614,11 +587,11 @@ func! s:PrtCurEnd()
let prt[2] = '' let prt[2] = ''
let prt[1] = '' let prt[1] = ''
let prt[0] = str let prt[0] = str
cal s:BuildPrompt() cal s:BuildPrompt(0)
endfunc endfunc
func! s:PrtDeleteWord() func! s:PrtDeleteWord()
let s:nomatches = 1 let s:matches = 1
unl! s:hstgot unl! s:hstgot
let prt = g:CtrlP_prompt let prt = g:CtrlP_prompt
let str = prt[0] let str = prt[0]
@ -632,7 +605,7 @@ func! s:PrtDeleteWord()
let str = '' let str = ''
endif endif
let prt[0] = str let prt[0] = str
cal s:BuildPrompt() cal s:BuildPrompt(1)
endfunc endfunc
func! s:PrtSelectMove(dir) func! s:PrtSelectMove(dir)
@ -641,7 +614,7 @@ func! s:PrtSelectMove(dir)
endfunc endfunc
func! s:PrtSelectJump(char,...) func! s:PrtSelectJump(char,...)
let lines = map(s:matched, 'substitute(v:val, "^> ", "", "g")') let lines = deepcopy(s:matched)
if exists('a:1') if exists('a:1')
let lines = map(lines, 'split(v:val, ''[\/]\ze[^\/]\+$'')[-1]') let lines = map(lines, 'split(v:val, ''[\/]\ze[^\/]\+$'')[-1]')
endif endif
@ -670,11 +643,20 @@ endfunc
func! s:PrtClearCache() func! s:PrtClearCache()
cal ctrlp#clearcache() cal ctrlp#clearcache()
cal s:SetLines(s:itemtype) cal s:SetLines(s:itemtype)
cal s:BuildPrompt() cal s:BuildPrompt(1)
endfunc
func! s:PrtExit()
if has('autocmd') && s:currwin
exe s:currwin.'winc w'
else
cal s:BufOpen('ControlP', 'del')
endif
endfunc endfunc
func! s:PrtHistory(...) func! s:PrtHistory(...)
if !s:maxhst | retu | endif if !s:maxhst | retu | endif
let s:matches = 1
let prt = g:CtrlP_prompt let prt = g:CtrlP_prompt
let str = prt[0] . prt[1] . prt[2] let str = prt[0] . prt[1] . prt[2]
let hst = s:hstry let hst = s:hstry
@ -687,7 +669,7 @@ func! s:PrtHistory(...)
let g:CtrlP_prompt = [hst[idx], '', ''] let g:CtrlP_prompt = [hst[idx], '', '']
let s:hisidx = idx let s:hisidx = idx
let s:hstgot = 1 let s:hstgot = 1
cal s:BuildPrompt() cal s:BuildPrompt(1)
endfunc endfunc
"}}} "}}}
@ -697,7 +679,7 @@ func! s:MapKeys(...)
let func = !exists('a:1') || ( exists('a:1') && a:1 ) ? 'PrtAdd' : 'PrtSelectJump' let func = !exists('a:1') || ( exists('a:1') && a:1 ) ? 'PrtAdd' : 'PrtSelectJump'
let sjbyfname = s:byfname && func == 'PrtSelectJump' ? ', 1' : '' let sjbyfname = s:byfname && func == 'PrtSelectJump' ? ', 1' : ''
for each in range(32,126) for each in range(32,126)
exe "nn \<buffer> \<silent> \<char-".each."> :cal \<SID>".func."(\"".escape(nr2char(each), '"|\')."\"".sjbyfname.")\<cr>" exe "nn \<buffer> \<silent> \<char-".each."> :<c-u>cal \<SID>".func."(\"".escape(nr2char(each), '"|\')."\"".sjbyfname.")\<cr>"
endfor endfor
if exists('a:2') | retu | endif if exists('a:2') | retu | endif
" Special keystrokes " Special keystrokes
@ -710,33 +692,32 @@ endfunc
func! s:MapSpecs(...) func! s:MapSpecs(...)
let prtmaps = { let prtmaps = {
\ 'PrtBS()': ['<bs>'], \ 'PrtBS()': ['<bs>'],
\ 'PrtDelete()': ['<del>'], \ 'PrtDelete()': ['<del>'],
\ 'PrtDeleteWord()': ['<c-w>'], \ 'PrtDeleteWord()': ['<c-w>'],
\ 'PrtClear()': ['<c-u>'], \ 'PrtClear()': ['<c-u>'],
\ 'PrtSelectMove("j")': ['<c-j>', '<down>'], \ 'PrtSelectMove("j")': ['<c-j>', '<down>'],
\ 'PrtSelectMove("k")': ['<c-k>', '<up>'], \ 'PrtSelectMove("k")': ['<c-k>', '<up>'],
\ 'PrtHistory(-1)': ['<c-n>'], \ 'PrtHistory(-1)': ['<c-n>'],
\ 'PrtHistory(1)': ['<c-p>'], \ 'PrtHistory(1)': ['<c-p>'],
\ 'AcceptSelection("e")': ['<cr>'], \ 'AcceptSelection("e")': ['<cr>'],
\ 'AcceptSelection("h")': ['<c-x>', '<c-cr>', '<c-s>'], \ 'AcceptSelection("h")': ['<c-x>', '<c-cr>', '<c-s>'],
\ 'AcceptSelection("t")': ['<c-t>'], \ 'AcceptSelection("t")': ['<c-t>'],
\ 'AcceptSelection("v")': ['<c-v>', '<c-q>'], \ 'AcceptSelection("v")': ['<c-v>', '<c-q>'],
\ 'ToggleFocus()': ['<tab>'], \ 'ToggleFocus()': ['<tab>'],
\ 'ToggleRegex()': ['<c-r>'], \ 'ToggleRegex()': ['<c-r>'],
\ 'ToggleByFname()': ['<c-d>'], \ 'ToggleByFname()': ['<c-d>'],
\ 'ToggleType(1)': ['<c-f>', '<c-up'], \ 'ToggleType(1)': ['<c-f>', '<c-up'],
\ 'ToggleType(-1)': ['<c-b>', '<c-down>'], \ 'ToggleType(-1)': ['<c-b>', '<c-down>'],
\ 'ForceUpdate()': ['<c-^>'], \ 'PrtCurStart()': ['<c-a>'],
\ 'PrtCurStart()': ['<c-a>'], \ 'PrtCurEnd()': ['<c-e>'],
\ 'PrtCurEnd()': ['<c-e>'], \ 'PrtCurLeft()': ['<c-h>', '<left>'],
\ 'PrtCurLeft()': ['<c-h>', '<left>'], \ 'PrtCurRight()': ['<c-l>', '<right>'],
\ 'PrtCurRight()': ['<c-l>', '<right>'], \ 'PrtClearCache()': ['<F5>'],
\ 'PrtClearCache()': ['<F5>'], \ 'CreateNewFile()': ['<c-y>'],
\ 'CreateNewFile()': ['<c-y>'], \ 'MarkToOpen()': ['<c-z>'],
\ 'MarkToOpen()': ['<c-z>'], \ 'OpenMulti()': ['<c-o>'],
\ 'OpenMulti()': ['<c-o>'], \ 'PrtExit()': ['<esc>', '<c-c>', '<c-g>'],
\ 'BufOpen("ControlP", "del")': ['<esc>', '<c-c>', '<c-g>'],
\ } \ }
if type(s:urprtmaps) == 4 if type(s:urprtmaps) == 4
cal extend(prtmaps, s:urprtmaps) cal extend(prtmaps, s:urprtmaps)
@ -765,7 +746,7 @@ func! s:MapSpecs(...)
endfor | endfor endfor | endfor
else else
for each in keys(prtmaps) | for kp in prtmaps[each] for each in keys(prtmaps) | for kp in prtmaps[each]
exe lcmap kp ':cal <SID>'.each.'<cr>' exe lcmap kp ':<c-u>cal <SID>'.each.'<cr>'
endfor | endfor endfor | endfor
endif endif
endfunc endfunc
@ -779,8 +760,7 @@ endfunc
func! s:ToggleFocus() func! s:ToggleFocus()
let s:focus = !exists('s:focus') || s:focus ? 0 : 1 let s:focus = !exists('s:focus') || s:focus ? 0 : 1
cal s:MapKeys(s:focus) cal s:MapKeys(s:focus)
let s:firstinit = 1 cal s:BuildPrompt(0,s:focus)
cal s:BuildPrompt(s:focus)
endfunc endfunc
func! s:ToggleRegex() func! s:ToggleRegex()
@ -808,9 +788,8 @@ func! s:Type(type)
endfunc endfunc
func! s:PrtSwitcher() func! s:PrtSwitcher()
let s:nomatches = 1 let s:matches = 1
let s:firstinit = 1 cal s:BuildPrompt(1,s:Focus())
cal s:BuildPrompt(s:Focus())
endfunc endfunc
"}}} "}}}
@ -838,8 +817,10 @@ func! ctrlp#SetWorkingPath(...)
\ || !s:pathmode || !l:pathmode \ || !s:pathmode || !l:pathmode
retu retu
endif endif
if exists('+acd') | se noacd | endif if exists('+acd') | let &acd = 0 | endif
sil! exe 'chd!' exists('*fnameescape') ? fnameescape(expand('%:p:h')) : expand('%:p:h') let path = expand('%:p:h')
let path = exists('*fnameescape') ? fnameescape(path) : escape(path, '%#')
sil! exe 'chd!' path
if s:pathmode == 1 || l:pathmode == 1 | retu | endif if s:pathmode == 1 || l:pathmode == 1 | retu | endif
let markers = [ let markers = [
\ 'root.dir', \ 'root.dir',
@ -878,23 +859,6 @@ func! s:AcceptSelection(mode,...) "{{{
if exists('a:1') && a:1 | retu filpath | endif if exists('a:1') && a:1 | retu filpath | endif
" Manually remove the prompt and match window " Manually remove the prompt and match window
if !has('autocmd') | cal s:BufOpen('ControlP', 'del') | endif if !has('autocmd') | cal s:BufOpen('ControlP', 'del') | endif
" Record the input string
cal s:recordhist(str)
" Split the mode string if it's longer than 1 char
if len(md) > 1
let mds = split(md, '\zs')
let md = mds[0]
endif
" Determine the command to use
if md == 't' || s:splitwin == 1 " In new tab
let cmd = 'e'
elseif md == 'h' || s:splitwin == 2 " In new hor split
let cmd = 'new'
elseif md == 'v' || s:splitwin == 3 " In new ver split
let cmd = 'vne'
elseif md == 'e' || !s:splitwin " In current window
let cmd = 'e'
endif
let bufnum = bufnr(filpath) let bufnum = bufnr(filpath)
let bufwinnr = bufwinnr(bufnum) let bufwinnr = bufwinnr(bufnum)
let norbuf = s:normbuf() let norbuf = s:normbuf()
@ -931,8 +895,16 @@ func! s:AcceptSelection(mode,...) "{{{
elseif bufnum > 0 && bufwinnr > 0 " In a window elseif bufnum > 0 && bufwinnr > 0 " In a window
exe bufwinnr.'winc w' exe bufwinnr.'winc w'
else else
" If mode is 'e' " Determine the command to use
if md == 'e' if md == 't' || s:splitwin == 1 " In new tab
tabnew
let cmd = 'e'
elseif md == 'h' || s:splitwin == 2 " In new hor split
let cmd = 'new'
elseif md == 'v' || s:splitwin == 3 " In new ver split
let cmd = 'vne'
elseif md == 'e' || !s:splitwin " In current window
let cmd = 'e'
" If there's at least 1 normal buffer " If there's at least 1 normal buffer
if norbuf if norbuf
" But not the current one " But not the current one
@ -944,8 +916,6 @@ func! s:AcceptSelection(mode,...) "{{{
" No normal buffers " No normal buffers
let cmd = 'vne' let cmd = 'vne'
endif endif
elseif md == 't'
tabnew
endif endif
" Open new window/buffer " Open new window/buffer
sil! exe 'bo '.cmd.tail.' '.filpath sil! exe 'bo '.cmd.tail.' '.filpath
@ -1042,7 +1012,7 @@ func! s:statusline(...)
let item = '%#Character# '.item.' %*' let item = '%#Character# '.item.' %*'
let slider = ' <'.prev.'>={'.item.'}=<'.next.'>' let slider = ' <'.prev.'>={'.item.'}=<'.next.'>'
let dir = ' %=%<%#LineNr# '.getcwd().' %*' let dir = ' %=%<%#LineNr# '.getcwd().' %*'
let marked = s:opmul ? exists('s:marked') ? ' <+'.len(s:marked).'>' : ' <+>' : '' let marked = s:opmul ? exists('s:marked') ? ' <'.s:dismarks(s:marked).'>' : ' <+>' : ''
let &l:stl = focus.byfname.regex.slider.marked.dir let &l:stl = focus.byfname.regex.slider.marked.dir
endfunc endfunc
@ -1052,6 +1022,21 @@ func! s:progress(len)
let &l:stl = cnt.dir let &l:stl = cnt.dir
redr redr
endfunc endfunc
func! s:dismarks(marked)
let marked = deepcopy(a:marked)
cal map(marked, 'split(v:val, "[\\/]")[-1]')
if has('signs')
let str = '+'.len(marked)
else
let str = '%<'
for each in values(marked)
let str .= ', '.each
endfor
let str = substitute(str, ', ', '', '')
endif
retu str
endfunc
"}}} "}}}
" Paths {{{ " Paths {{{
@ -1074,6 +1059,21 @@ func! s:createparentdirs(arr)
endfor endfor
retu curr retu curr
endfunc endfunc
func! s:listdirs(path,parent)
let str = ''
for entry in filter(split(globpath(a:path, '*'), '\n'), 'isdirectory(v:val)')
let str .= a:parent.split(entry, '[\/]')[-1] . "\n"
endfor
retu str
endfunc
func! ctrlp#compl(A,L,P)
let haslash = match(a:A, '[\/]')
let parent = substitute(a:A, '[^\/]*$', '', 'g')
let path = !haslash ? parent : haslash > 0 ? getcwd().s:lash.parent : getcwd()
retu s:listdirs(path,parent)
endfunc
"}}} "}}}
" Highlighting {{{ " Highlighting {{{
@ -1133,7 +1133,6 @@ endfunc
func! s:remarksigns(nls) func! s:remarksigns(nls)
if !s:dosigns() | retu | endif if !s:dosigns() | retu | endif
let nls = deepcopy(a:nls) let nls = deepcopy(a:nls)
cal map(nls, 'substitute(v:val, "^> ", "", "g")')
let ic = 1 let ic = 1
while ic <= len(nls) while ic <= len(nls)
let filpath = s:itemtype ? nls[ic - 1] : getcwd().s:lash.nls[ic - 1] let filpath = s:itemtype ? nls[ic - 1] : getcwd().s:lash.nls[ic - 1]
@ -1150,6 +1149,62 @@ func! s:dosigns()
endfunc endfunc
"}}} "}}}
" Dictionaries {{{
func! s:dictindex(dict, expr)
for key in keys(a:dict)
let val = a:dict[key]
if val == a:expr
retu key
endif
endfor
retu -1
endfunc
func! s:vacantdict(dict)
let vac = []
for ic in range(1, max(keys(a:dict)))
if !has_key(a:dict, ic)
cal add(vac, ic)
endif
endfor
retu vac
endfunc
"}}}
" Buffers {{{
func! s:normbuf()
if &l:bl && empty(&l:bt) && &l:ma | retu winnr() | endif
for each in range(1, winnr('$'))
let bufnr = winbufnr(each)
if getbufvar(bufnr, '&bl') && empty(getbufvar(bufnr, '&bt'))
\ && getbufvar(bufnr, '&ma')
retu each
endif
endfor
retu 0
endfunc
func! s:setupblank()
setl noswf nobl nonu nowrap nolist nospell cul nocuc wfh tw=0 bt=nofile bh=unload
if v:version >= '703'
setl nornu noudf cc=0
endif
endfunc
func! s:leavepre()
if s:cconex | cal ctrlp#clearallcaches() | endif
cal ctrlp#utils#writecache(s:hstry, s:gethistloc()[0], s:gethistloc()[1])
endfunc
func! s:checkbuf()
if exists('s:init') | retu | endif
if exists('s:bufnr') && s:bufnr > 0
exe s:bufnr.'bw!'
unl! s:bufnr
endif
endfunc
"}}}
" Misc {{{ " Misc {{{
func! s:walker(max, pos, dir, ...) func! s:walker(max, pos, dir, ...)
if a:dir == 1 if a:dir == 1
@ -1172,40 +1227,6 @@ func! s:maxfiles(len)
retu s:maxfiles && a:len > s:maxfiles ? 1 : 0 retu s:maxfiles && a:len > s:maxfiles ? 1 : 0
endfunc endfunc
func! s:dictindex(dict, expr)
for key in keys(a:dict)
let val = a:dict[key]
if val == a:expr
retu key
endif
endfor
retu -1
endfunc
func! s:vacantdict(dict)
let vac = []
for ic in range(1, max(keys(a:dict)))
if !has_key(a:dict, ic)
cal add(vac, ic)
endif
endfor
retu vac
endfunc
func! s:normbuf()
if &l:bl && empty(&l:bt) && &l:ma | retu winnr() | endif
for each in range(1, winnr('$'))
winc w
if &l:bl && empty(&l:bt) && &l:ma | retu each | endif
endfor
retu 0
endfunc
func! s:leavepre()
if s:cconex | cal ctrlp#clearallcaches() | endif
cal ctrlp#utils#writecache(s:hstry, s:gethistloc()[0], s:gethistloc()[1])
endfunc
func! s:insertcache(str) func! s:insertcache(str)
let cache_file = ctrlp#utils#cachefile() let cache_file = ctrlp#utils#cachefile()
if filereadable(cache_file) if filereadable(cache_file)
@ -1236,7 +1257,8 @@ endfunc
if has('autocmd') "{{{ if has('autocmd') "{{{
aug CtrlPAug aug CtrlPAug
au! au!
au WinLeave,BufLeave ControlP cal s:BufOpen('ControlP', 'del') au BufEnter ControlP cal s:checkbuf()
au BufLeave ControlP cal s:BufOpen('ControlP', 'del')
au VimLeavePre * cal s:leavepre() au VimLeavePre * cal s:leavepre()
aug END aug END
endif "}}} endif "}}}
@ -1253,15 +1275,16 @@ func! s:SetLines(type)
endfunc endfunc
func! ctrlp#init(type, ...) func! ctrlp#init(type, ...)
let s:nomatches = 1 if exists('s:init') | retu | endif
let s:firstinit = 1 let s:matches = 1
let s:init = 1
let a1 = exists('a:1') ? a:1 : '' let a1 = exists('a:1') ? a:1 : ''
cal ctrlp#SetWorkingPath(a1) cal ctrlp#SetWorkingPath(a1)
cal s:BufOpen('ControlP') cal s:BufOpen('ControlP')
cal s:SetupBlank() cal s:setupblank()
cal s:MapKeys() cal s:MapKeys()
cal s:SetLines(a:type) cal s:SetLines(a:type)
cal s:BuildPrompt() cal s:BuildPrompt(1)
cal s:syntax() cal s:syntax()
endfunc endfunc
"}}} "}}}

View File

@ -12,7 +12,7 @@ endif "}}}
" Option variables {{{ " Option variables {{{
func! ctrlp#mrufiles#opts() func! ctrlp#mrufiles#opts()
if !exists('g:ctrlp_mruf_max') if !exists('g:ctrlp_mruf_max')
let s:max = 50 let s:max = 150
else else
let s:max = g:ctrlp_mruf_max let s:max = g:ctrlp_mruf_max
unl g:ctrlp_mruf_max unl g:ctrlp_mruf_max

View File

@ -1,4 +1,4 @@
*ctrlp.txt* Full path fuzzy file, buffer and MRU file finder. v1.5 *ctrlp.txt* Full path fuzzy file, buffer and MRU file finder. v1.5.1
*CtrlP* *ControlP* *'ctrlp'* *'ctrl-p'* *CtrlP* *ControlP* *'ctrlp'* *'ctrl-p'*
=============================================================================== ===============================================================================
# # # #
@ -25,7 +25,8 @@ CONTENTS *ctrlp-contents*
Full path fuzzy file, buffer and MRU file finder with an intuitive interface. Full path fuzzy file, buffer and MRU file finder with an intuitive interface.
Written in pure Vimscript for MacVim and Vim version 7.0+. Has full support for Written in pure Vimscript for MacVim and Vim version 7.0+. Has full support for
Vims |regexp| as search pattern, and more. Vims |regexp| as search pattern, built-in MRU monitoring, projects root
finder, and more.
See also |ctrlp-input-formats| and |ctrlp-fullregexp|. See also |ctrlp-input-formats| and |ctrlp-fullregexp|.
@ -54,15 +55,6 @@ Set this to 1 to set full |regexp| search as the default mode: >
let g:ctrlp_regexp_search = 0 let g:ctrlp_regexp_search = 0
< <
*'g:ctrlp_persistent_input'*
Remember the last input string:
1 - Remember the last input string.
2 - Also remember the position of the selection in the match window.
0 - Clear the input field each time CtrlP starts.
>
let g:ctrlp_persistent_input = 0
<
*'g:ctrlp_match_window_reversed'* *'g:ctrlp_match_window_reversed'*
Reverse the sort order of the matched files in the match window. The default Reverse the sort order of the matched files in the match window. The default
setting is from bottom to top: > setting is from bottom to top: >
@ -133,33 +125,32 @@ Set the parent directory for the '.ctrlp_cache' directory: >
Use this to customize the mappings inside |CtrlP|s prompt to your liking. You Use this to customize the mappings inside |CtrlP|s prompt to your liking. You
only need to keep the lines that youve changed the values (inside []): > only need to keep the lines that youve changed the values (inside []): >
let g:ctrlp_prompt_mappings = { let g:ctrlp_prompt_mappings = {
\ 'PrtBS()': ['<bs>'], \ 'PrtBS()': ['<bs>'],
\ 'PrtDelete()': ['<del>'], \ 'PrtDelete()': ['<del>'],
\ 'PrtDeleteWord()': ['<c-w>'], \ 'PrtDeleteWord()': ['<c-w>'],
\ 'PrtClear()': ['<c-u>'], \ 'PrtClear()': ['<c-u>'],
\ 'PrtSelectMove("j")': ['<c-j>', '<down>'], \ 'PrtSelectMove("j")': ['<c-j>', '<down>'],
\ 'PrtSelectMove("k")': ['<c-k>', '<up>'], \ 'PrtSelectMove("k")': ['<c-k>', '<up>'],
\ 'PrtHistory(-1)': ['<c-n>'], \ 'PrtHistory(-1)': ['<c-n>'],
\ 'PrtHistory(1)': ['<c-p>'], \ 'PrtHistory(1)': ['<c-p>'],
\ 'AcceptSelection("e")': ['<cr>'], \ 'AcceptSelection("e")': ['<cr>'],
\ 'AcceptSelection("h")': ['<c-x>', '<c-cr>', '<c-s>'], \ 'AcceptSelection("h")': ['<c-x>', '<c-cr>', '<c-s>'],
\ 'AcceptSelection("t")': ['<c-t>'], \ 'AcceptSelection("t")': ['<c-t>'],
\ 'AcceptSelection("v")': ['<c-v>'], \ 'AcceptSelection("v")': ['<c-v>', '<c-q>'],
\ 'ToggleFocus()': ['<tab>'], \ 'ToggleFocus()': ['<tab>'],
\ 'ToggleRegex()': ['<c-r>'], \ 'ToggleRegex()': ['<c-r>'],
\ 'ToggleByFname()': ['<c-d>'], \ 'ToggleByFname()': ['<c-d>'],
\ 'ToggleType(1)': ['<c-f>', '<c-up'], \ 'ToggleType(1)': ['<c-f>', '<c-up'],
\ 'ToggleType(-1)': ['<c-b>', '<c-down>'], \ 'ToggleType(-1)': ['<c-b>', '<c-down>'],
\ 'ForceUpdate()': ['<c-^>'], \ 'PrtCurStart()': ['<c-a>'],
\ 'PrtCurStart()': ['<c-a>'], \ 'PrtCurEnd()': ['<c-e>'],
\ 'PrtCurEnd()': ['<c-e>'], \ 'PrtCurLeft()': ['<c-h>', '<left>'],
\ 'PrtCurLeft()': ['<c-h>', '<left>'], \ 'PrtCurRight()': ['<c-l>', '<right>'],
\ 'PrtCurRight()': ['<c-l>', '<right>'], \ 'PrtClearCache()': ['<F5>'],
\ 'PrtClearCache()': ['<F5>'], \ 'CreateNewFile()': ['<c-y>'],
\ 'CreateNewFile()': ['<c-y>'], \ 'MarkToOpen()': ['<c-z>'],
\ 'MarkToOpen()': ['<c-z>'], \ 'OpenMulti()': ['<c-o>'],
\ 'OpenMulti()': ['<c-o>'], \ 'PrtExit()': ['<esc>', '<c-c>', '<c-g>'],
\ 'BufOpen("ControlP", "del")': ['<esc>', '<c-c>', '<c-g>'],
\ } \ }
< <
@ -170,7 +161,7 @@ Set this to 0 to completely disable the Most Recently Used files feature: >
*'g:ctrlp_mruf_max'* *'g:ctrlp_mruf_max'*
Specify the number of recently opened files you want |CtrlP| to remember: > Specify the number of recently opened files you want |CtrlP| to remember: >
let g:ctrlp_mruf_max = 50 let g:ctrlp_mruf_max = 150
< <
*'g:ctrlp_mruf_exclude'* *'g:ctrlp_mruf_exclude'*
@ -208,7 +199,7 @@ this.
*'g:ctrlp_highlight_match'* *'g:ctrlp_highlight_match'*
Use this to enable/disable highlighting of the matched patterns and to specify Use this to enable/disable highlighting of the matched patterns and to specify
the highlight group thatll be used: > the highlight group thatll be used: >
let g:ctrlp_highlight_match = [1, 'Function'] let g:ctrlp_highlight_match = [1, 'Identifier']
< <
*'g:ctrlp_max_files'* *'g:ctrlp_max_files'*
@ -222,12 +213,6 @@ The maximum depth of a directory tree to recurse into: >
< <
Note: the larger the value, the more memory Vim uses. Note: the larger the value, the more memory Vim uses.
*'g:ctrlp_live_update'*
Set to 0 to disable the update-as-you-type functionality; press <c-^> to force
an update: >
let g:ctrlp_live_update = 1
<
*'g:ctrlp_user_command'* *'g:ctrlp_user_command'*
Specify an external tool to use for indexing files instead of Vims globpath(). Specify an external tool to use for indexing files instead of Vims globpath().
Use %s in place of the target directory: > Use %s in place of the target directory: >
@ -277,6 +262,7 @@ files, each in a vertical split.
Open the |CtrlP| prompt in find files mode. Open the |CtrlP| prompt in find files mode.
If no argument is given, the value of |g:ctrlp_working_path_mode| will be If no argument is given, the value of |g:ctrlp_working_path_mode| will be
used to determine the starting directory. used to determine the starting directory.
You can use <tab> to auto-complete the path when typing it.
*:CtrlPBuffer* *:CtrlPBuffer*
:CtrlPBuffer :CtrlPBuffer
@ -407,10 +393,6 @@ Once inside the prompt:
<F5> <F5>
Refresh the match window and purge the cache for the current directory. Refresh the match window and purge the cache for the current directory.
<c-^>
Force update the match window.
You only need to use this if |g:ctrlp_live_update| has been set to 0.
<esc>, <esc>,
<c-c>, <c-c>,
<c-g> <c-g>
@ -472,6 +454,8 @@ liked the way Command-T and LustyExplorer deal with users input, so I wrote a
pure Vimscript version of their prompt window, intended to use it for the pure Vimscript version of their prompt window, intended to use it for the
aforementioned plugin. aforementioned plugin.
Homepage: http://kien.github.com/ctrlp.vim
Git repository: https://github.com/kien/ctrlp.vim Git repository: https://github.com/kien/ctrlp.vim
Mercurial repository: https://bitbucket.org/kien/ctrlp.vim Mercurial repository: https://bitbucket.org/kien/ctrlp.vim
@ -480,9 +464,11 @@ CHANGELOG
+ New features: Open multiple files. + New features: Open multiple files.
Pass Vims ++opt and +cmd to the opening file (section 5.c) Pass Vims ++opt and +cmd to the opening file (section 5.c)
Auto-complete each dir for |:CtrlP| [starting-directory]
+ New mappings: <c-z> mark/unmark a file to be opened with <c-o>. + New mappings: <c-z> mark/unmark a file to be opened with <c-o>.
<c-o> open all marked files. <c-o> open all marked files.
+ New option: |g:ctrlp_open_multi| + New option: |g:ctrlp_open_multi|
+ Remove |g:ctrlp_persistent_input|, |g:ctrlp_live_update| and <c-^>.
Before 2011/09/29 Before 2011/09/29
@ -524,5 +510,7 @@ Before 2011/09/12
|g:ctrlp_mruf_include| |g:ctrlp_mruf_include|
+ New command: |:CtrlPMRUFiles| + New command: |:CtrlPMRUFiles|
First public release: 2011/09/06
=============================================================================== ===============================================================================
vim:et:ts=2:sw=2:sts=2 vim:et:ts=2:sw=2:sts=2

View File

@ -4,6 +4,7 @@
" Author: Kien Nguyen <github.com/kien> " Author: Kien Nguyen <github.com/kien>
" License: MIT " License: MIT
" ============================================================================= " =============================================================================
" GetLatestVimScripts: 3736 1 :AutoInstall: ctrlp.zip
if ( exists('g:loaded_ctrlp') && g:loaded_ctrlp ) || v:version < '700' || &cp if ( exists('g:loaded_ctrlp') && g:loaded_ctrlp ) || v:version < '700' || &cp
fini fini
@ -13,7 +14,8 @@ let g:loaded_ctrlp = 1
if !exists('g:ctrlp_map') | let g:ctrlp_map = '<c-p>' | endif if !exists('g:ctrlp_map') | let g:ctrlp_map = '<c-p>' | endif
if !exists('g:ctrlp_mru_files') | let g:ctrlp_mru_files = 1 | endif if !exists('g:ctrlp_mru_files') | let g:ctrlp_mru_files = 1 | endif
com! -nargs=? CtrlP cal ctrlp#init(0, <q-args>) com! -nargs=? -complete=custom,ctrlp#compl CtrlP cal ctrlp#init(0, <q-args>)
com! CtrlPBuffer cal ctrlp#init(1) com! CtrlPBuffer cal ctrlp#init(1)
com! CtrlPMRUFiles cal ctrlp#init(2) com! CtrlPMRUFiles cal ctrlp#init(2)
com! ClearCtrlPCache cal ctrlp#clearcache() com! ClearCtrlPCache cal ctrlp#clearcache()

View File

@ -2,8 +2,9 @@
Full path fuzzy __file__, __buffer__ and __MRU__ file finder for Vim. Full path fuzzy __file__, __buffer__ and __MRU__ file finder for Vim.
* Written in pure Vimscript for MacVim and Vim 7.0+. * Written in pure Vimscript for MacVim and Vim 7.0+.
* Has full support for Vims regexp as search pattern. * Full support for Vims regexp as search pattern.
* Can also find file in most recently used files. * Built-in Most Recently Used (MRU) files monitoring.
* Built-in projects root finder.
![ctrlp][1] ![ctrlp][1]