sorting and escaping
This commit is contained in:
parent
719df0ec79
commit
c360f2db47
@ -42,7 +42,7 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if !exists('g:ctrlp_ignore_space')
|
if !exists('g:ctrlp_ignore_space')
|
||||||
let s:igspace = 1
|
let s:igspace = 0
|
||||||
else
|
else
|
||||||
let s:igspace = g:ctrlp_ignore_space
|
let s:igspace = g:ctrlp_ignore_space
|
||||||
unl g:ctrlp_ignore_space
|
unl g:ctrlp_ignore_space
|
||||||
@ -228,9 +228,10 @@ func! s:ListAllBuffers() "{{{
|
|||||||
endfunc "}}}
|
endfunc "}}}
|
||||||
|
|
||||||
func! s:SplitPattern(str,...) "{{{
|
func! s:SplitPattern(str,...) "{{{
|
||||||
|
let str = a:str
|
||||||
" ignore spaces
|
" ignore spaces
|
||||||
if s:igspace
|
if s:igspace
|
||||||
let str = substitute(a:str, ' ', '', 'g')
|
let str = substitute(str, ' ', '', 'g')
|
||||||
endif
|
endif
|
||||||
" clear the jumptoline var
|
" clear the jumptoline var
|
||||||
if exists('s:jmpln') | unl s:jmpln | endif
|
if exists('s:jmpln') | unl s:jmpln | endif
|
||||||
@ -241,15 +242,19 @@ func! s:SplitPattern(str,...) "{{{
|
|||||||
" remove the line number
|
" remove the line number
|
||||||
let str = substitute(str, ':\d*$', '', 'g')
|
let str = substitute(str, ':\d*$', '', 'g')
|
||||||
endif
|
endif
|
||||||
if s:regexp || match(str, '[*^$+|]') >= 0
|
|
||||||
\ || match(str, '\\\(zs\|ze\|<\|>\)') >= 0
|
|
||||||
let str = substitute(str, '\\\\', '\', 'g')
|
let str = substitute(str, '\\\\', '\', 'g')
|
||||||
|
if s:regexp || match(str, '[*|]') >= 0
|
||||||
|
\ || match(str, '\\\(zs\|ze\|<\|>\)') >= 0
|
||||||
let array = [str]
|
let array = [str]
|
||||||
else
|
else
|
||||||
let array = split(str, '\zs')
|
let array = split(str, '\zs')
|
||||||
if exists('+ssl') && !&ssl
|
if exists('+ssl') && !&ssl
|
||||||
cal map(array, 'substitute(v:val, "\\", "\\\\\\\\", "g")')
|
cal map(array, 'substitute(v:val, "\\", "\\\\\\", "g")')
|
||||||
endif
|
endif
|
||||||
|
" literal ^ and $
|
||||||
|
for each in ['^', '$']
|
||||||
|
cal map(array, 'substitute(v:val, "\\\'.each.'", "\\\\\\'.each.'", "g")')
|
||||||
|
endfor
|
||||||
endif
|
endif
|
||||||
" Build the new pattern
|
" Build the new pattern
|
||||||
let nitem = !empty(array) ? array[0] : ''
|
let nitem = !empty(array) ? array[0] : ''
|
||||||
@ -280,6 +285,7 @@ func! s:GetMatchedItems(items, pats, limit) "{{{
|
|||||||
if exists('newitems') && len(newitems) < limit
|
if exists('newitems') && len(newitems) < limit
|
||||||
let items = deepcopy(newitems)
|
let items = deepcopy(newitems)
|
||||||
endif
|
endif
|
||||||
|
if !s:regexp | let each = escape(each, '.') | endif
|
||||||
if empty(items) " end here
|
if empty(items) " end here
|
||||||
retu exists('newitems') ? newitems : []
|
retu exists('newitems') ? newitems : []
|
||||||
else " start here, goes back up if has 2 or more in pats
|
else " start here, goes back up if has 2 or more in pats
|
||||||
@ -408,7 +414,7 @@ func! s:Renderer(lines, pat) "{{{
|
|||||||
" don't sort
|
" don't sort
|
||||||
if index([2], s:itemtype) < 0
|
if index([2], s:itemtype) < 0
|
||||||
let s:compat = a:pat
|
let s:compat = a:pat
|
||||||
cal sort(nls, 's:comatlen')
|
cal sort(nls, 's:mixedsort')
|
||||||
unl s:compat
|
unl s:compat
|
||||||
endif
|
endif
|
||||||
if s:mwreverse
|
if s:mwreverse
|
||||||
@ -436,8 +442,8 @@ func! s:UpdateMatches(pat) "{{{
|
|||||||
" Delete the buffer's content
|
" Delete the buffer's content
|
||||||
sil! %d _
|
sil! %d _
|
||||||
let pats = s:SplitPattern(a:pat)
|
let pats = s:SplitPattern(a:pat)
|
||||||
let pat = pats[-1]
|
|
||||||
let lines = s:GetMatchedItems(s:lines, pats, s:mxheight)
|
let lines = s:GetMatchedItems(s:lines, pats, s:mxheight)
|
||||||
|
let pat = pats[-1]
|
||||||
cal s:Renderer(lines, pat)
|
cal s:Renderer(lines, pat)
|
||||||
" highlighting
|
" highlighting
|
||||||
if type(s:mathi) == 3 && len(s:mathi) == 2 && s:mathi[0] && exists('*clearmatches')
|
if type(s:mathi) == 3 && len(s:mathi) == 2 && s:mathi[0] && exists('*clearmatches')
|
||||||
@ -456,7 +462,8 @@ func! s:BuildPrompt(...) "{{{
|
|||||||
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
|
if s:nomatches
|
||||||
cal s:UpdateMatches(str)
|
" note: add sil! back after testing
|
||||||
|
sil! cal s:UpdateMatches(str)
|
||||||
endif
|
endif
|
||||||
cal s:statusline()
|
cal s:statusline()
|
||||||
" Toggling
|
" Toggling
|
||||||
@ -769,6 +776,7 @@ func! s:AcceptSelection(mode,...) "{{{
|
|||||||
let str = prt[0] . prt[1] . prt[2]
|
let str = prt[0] . prt[1] . prt[2]
|
||||||
if str == '..'
|
if str == '..'
|
||||||
cal s:parentdir(getcwd())
|
cal s:parentdir(getcwd())
|
||||||
|
cal s:SetLines(s:itemtype)
|
||||||
cal s:PrtClear()
|
cal s:PrtClear()
|
||||||
retu
|
retu
|
||||||
endif
|
endif
|
||||||
@ -799,9 +807,8 @@ func! s:AcceptSelection(mode,...) "{{{
|
|||||||
let bufnum = bufnr(filpath)
|
let bufnum = bufnr(filpath)
|
||||||
let bufwinnr = bufwinnr(bufnum)
|
let bufwinnr = bufwinnr(bufnum)
|
||||||
" check if the buffer's already opened in a tab
|
" check if the buffer's already opened in a tab
|
||||||
let nr = 1
|
for nr in range(1, tabpagenr('$'))
|
||||||
while nr <= tabpagenr('$')
|
" get a list of the buffers in the nr tab
|
||||||
" get list of buffers in the nr tab
|
|
||||||
let buflist = tabpagebuflist(nr)
|
let buflist = tabpagebuflist(nr)
|
||||||
" if it has the buffer we're looking for
|
" if it has the buffer we're looking for
|
||||||
if match(buflist, bufnum) >= 0
|
if match(buflist, bufnum) >= 0
|
||||||
@ -809,16 +816,13 @@ func! s:AcceptSelection(mode,...) "{{{
|
|||||||
" get the number of windows
|
" get the number of windows
|
||||||
let tabwinnrs = tabpagewinnr(nr, '$')
|
let tabwinnrs = tabpagewinnr(nr, '$')
|
||||||
" find the buffer that we know is in this tab
|
" find the buffer that we know is in this tab
|
||||||
let ewin = 1
|
for ewin in range(1, tabwinnrs)
|
||||||
while ewin <= tabwinnrs
|
|
||||||
if buflist[ewin - 1] == bufnum
|
if buflist[ewin - 1] == bufnum
|
||||||
let buftabwinnr = ewin
|
let buftabwinnr = ewin
|
||||||
endif
|
endif
|
||||||
let ewin += 1
|
endfor
|
||||||
endwhile
|
|
||||||
endif
|
endif
|
||||||
let nr += 1
|
endfor
|
||||||
endwhile
|
|
||||||
" switch to the buffer or open the file
|
" switch to the buffer or open the file
|
||||||
if bufnum > 0
|
if bufnum > 0
|
||||||
if exists('buftabwinnr')
|
if exists('buftabwinnr')
|
||||||
@ -841,23 +845,22 @@ func! s:AcceptSelection(mode,...) "{{{
|
|||||||
endfunc "}}}
|
endfunc "}}}
|
||||||
|
|
||||||
" * Helper functions {{{
|
" * Helper functions {{{
|
||||||
|
" comparing and sorting {{{
|
||||||
func! s:compare(s1, s2)
|
func! s:compare(s1, s2)
|
||||||
" by length
|
" by length
|
||||||
let str1 = strlen(a:s1)
|
let len1 = strlen(a:s1)
|
||||||
let str2 = strlen(a:s2)
|
let len2 = strlen(a:s2)
|
||||||
retu str1 == str2 ? 0 : str1 > str2 ? 1 : -1
|
retu len1 == len2 ? 0 : len1 > len2 ? 1 : -1
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func! s:comatlen(s1, s2)
|
func! s:compmatlen(s1, s2)
|
||||||
" by match length
|
" by match length
|
||||||
let str1 = min(s:smatstr(a:s1, s:compat))
|
let mln1 = min(s:matchlens(a:s1, s:compat))
|
||||||
let str2 = min(s:smatstr(a:s2, s:compat))
|
let mln2 = min(s:matchlens(a:s2, s:compat))
|
||||||
retu str1 == str2 ? 0 : str1 > str2 ? 1 : -1
|
retu mln1 == mln2 ? 0 : mln1 > mln2 ? 1 : -1
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
" find shortest match in a string
|
func! s:matchlens(str, pat, ...)
|
||||||
" return a list with lengths of the matches
|
|
||||||
func! s:smatstr(str, pat, ...)
|
|
||||||
if empty(a:pat) || a:pat == '$' || a:pat == '^'
|
if empty(a:pat) || a:pat == '$' || a:pat == '^'
|
||||||
retu []
|
retu []
|
||||||
endif
|
endif
|
||||||
@ -865,28 +868,21 @@ func! s:smatstr(str, pat, ...)
|
|||||||
let lens = exists('a:2') ? a:2 : []
|
let lens = exists('a:2') ? a:2 : []
|
||||||
if match(a:str, a:pat, st) != -1
|
if match(a:str, a:pat, st) != -1
|
||||||
let start = match(a:str, a:pat, st)
|
let start = match(a:str, a:pat, st)
|
||||||
let len = len(matchstr(a:str, a:pat, st))
|
let str = matchstr(a:str, a:pat, st)
|
||||||
|
let len = len(str)
|
||||||
let end = matchend(a:str, a:pat, st)
|
let end = matchend(a:str, a:pat, st)
|
||||||
let lens = add(lens, len)
|
let lens = add(lens, len)
|
||||||
let lens = s:smatstr(a:str, a:pat, end, lens)
|
let lens = s:matchlens(a:str, a:pat, end, lens)
|
||||||
endif
|
endif
|
||||||
retu lens
|
retu lens
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func! s:walker(max, pos, dir, ...)
|
func! s:mixedsort(s1, s2)
|
||||||
if a:dir == 1
|
retu 2 * s:compmatlen(a:s1, a:s2) + s:compare(a:s1, a:s2)
|
||||||
let pos = a:pos < a:max ? a:pos + 1 : 0
|
|
||||||
elseif a:dir == -1
|
|
||||||
let pos = a:pos > 0 ? a:pos - 1 : a:max
|
|
||||||
endif
|
|
||||||
if !g:ctrlp_mru_files && pos == 2
|
|
||||||
\ && !exists('a:1')
|
|
||||||
let jmp = pos == a:max ? 0 : 3
|
|
||||||
let pos = a:pos == 1 ? jmp : 1
|
|
||||||
endif
|
|
||||||
retu pos
|
|
||||||
endfunc
|
endfunc
|
||||||
|
"}}}
|
||||||
|
|
||||||
|
" dealing with statusline {{{
|
||||||
func! s:statusline(...)
|
func! s:statusline(...)
|
||||||
let itemtypes = {
|
let itemtypes = {
|
||||||
\ 0: ['files', 'fil'],
|
\ 0: ['files', 'fil'],
|
||||||
@ -910,15 +906,13 @@ func! s:statusline(...)
|
|||||||
exe 'setl stl='.focus.byfname.regex.slider
|
exe 'setl stl='.focus.byfname.regex.slider
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func! s:matchsubstr(item, pat)
|
|
||||||
retu match(split(a:item, '[\/]\ze[^\/]\+$')[-1], a:pat)
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
func! s:progress(len)
|
func! s:progress(len)
|
||||||
exe 'setl stl=%#Function#\ '.a:len.'\ %*\ '
|
exe 'setl stl=%#Function#\ '.a:len.'\ %*\ '
|
||||||
redr
|
redr
|
||||||
endfunc
|
endfunc
|
||||||
|
"}}}
|
||||||
|
|
||||||
|
" working with paths {{{
|
||||||
func! s:dirfilter(val)
|
func! s:dirfilter(val)
|
||||||
if isdirectory(a:val) && match(a:val, '[\/]\.\{,2}$') < 0
|
if isdirectory(a:val) && match(a:val, '[\/]\.\{,2}$') < 0
|
||||||
retu 1
|
retu 1
|
||||||
@ -931,9 +925,10 @@ func! s:parentdir(curr)
|
|||||||
if parent != a:curr
|
if parent != a:curr
|
||||||
exe 'chdir' parent
|
exe 'chdir' parent
|
||||||
endif
|
endif
|
||||||
cal s:SetLines(s:itemtype)
|
|
||||||
endfunc
|
endfunc
|
||||||
|
"}}}
|
||||||
|
|
||||||
|
" syntax and coloring {{{
|
||||||
func! s:syntax()
|
func! s:syntax()
|
||||||
syn match CtrlPNoEntries '^ == NO MATCHES ==$'
|
syn match CtrlPNoEntries '^ == NO MATCHES ==$'
|
||||||
syn match CtrlPLineMarker '^>'
|
syn match CtrlPLineMarker '^>'
|
||||||
@ -945,12 +940,10 @@ func! s:highlight(pat, grp)
|
|||||||
cal clearmatches()
|
cal clearmatches()
|
||||||
if !empty(a:pat) && a:pat != '..'
|
if !empty(a:pat) && a:pat != '..'
|
||||||
let pat = substitute(a:pat, '\~', '\\~', 'g')
|
let pat = substitute(a:pat, '\~', '\\~', 'g')
|
||||||
if !s:regexp
|
if !s:regexp | let pat = escape(pat, '.') | endif
|
||||||
let pat = escape(pat, '.')
|
|
||||||
endif
|
|
||||||
" match only filename
|
" match only filename
|
||||||
if s:byfname
|
if s:byfname
|
||||||
let pat = substitute(pat, '\.\\{-}', '[^\\/]\\{-}', 'g')
|
let pat = substitute(pat, '\[\^\(.\{-}\)\]\\{-}', '[^\\/\1]\\{-}', 'g')
|
||||||
let pat = substitute(pat, '$', '\\ze[^\\/]*$', 'g')
|
let pat = substitute(pat, '$', '\\ze[^\\/]*$', 'g')
|
||||||
endif
|
endif
|
||||||
cal matchadd(a:grp, '\c'.pat)
|
cal matchadd(a:grp, '\c'.pat)
|
||||||
@ -959,6 +952,27 @@ func! s:highlight(pat, grp)
|
|||||||
endfunc
|
endfunc
|
||||||
"}}}
|
"}}}
|
||||||
|
|
||||||
|
" misc {{{
|
||||||
|
func! s:walker(max, pos, dir, ...)
|
||||||
|
if a:dir == 1
|
||||||
|
let pos = a:pos < a:max ? a:pos + 1 : 0
|
||||||
|
elseif a:dir == -1
|
||||||
|
let pos = a:pos > 0 ? a:pos - 1 : a:max
|
||||||
|
endif
|
||||||
|
if !g:ctrlp_mru_files && pos == 2
|
||||||
|
\ && !exists('a:1')
|
||||||
|
let jmp = pos == a:max ? 0 : 3
|
||||||
|
let pos = a:pos == 1 ? jmp : 1
|
||||||
|
endif
|
||||||
|
retu pos
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! s:matchsubstr(item, pat)
|
||||||
|
retu match(split(a:item, '[\/]\ze[^\/]\+$')[-1], a:pat)
|
||||||
|
endfunc
|
||||||
|
"}}}
|
||||||
|
"}}}
|
||||||
|
|
||||||
" * Initialization {{{
|
" * Initialization {{{
|
||||||
func! s:SetLines(type)
|
func! s:SetLines(type)
|
||||||
let s:itemtype = a:type
|
let s:itemtype = a:type
|
||||||
|
@ -78,8 +78,8 @@ Use this option to specify how the file is to be opened when pressing <cr>:
|
|||||||
<
|
<
|
||||||
|
|
||||||
*'g:ctrlp_ignore_space'*
|
*'g:ctrlp_ignore_space'*
|
||||||
If you want the search to include whitespaces, change this to 0: >
|
Set this to 1 to ignore whitespaces in filenames and directory names: >
|
||||||
let g:ctrlp_ignore_space = 1
|
let g:ctrlp_ignore_space = 0
|
||||||
<
|
<
|
||||||
|
|
||||||
*'g:ctrlp_working_path_mode'*
|
*'g:ctrlp_working_path_mode'*
|
||||||
@ -227,7 +227,7 @@ Examples: >
|
|||||||
:CtrlP [starting-directory]
|
:CtrlP [starting-directory]
|
||||||
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 determined the starting directory.
|
used to determine the starting directory.
|
||||||
|
|
||||||
*:CtrlPBuffer*
|
*:CtrlPBuffer*
|
||||||
:CtrlPBuffer
|
:CtrlPBuffer
|
||||||
@ -271,8 +271,7 @@ The following commands ignore the value of |g:ctrlp_working_path_mode|:
|
|||||||
Once inside the prompt:
|
Once inside the prompt:
|
||||||
|
|
||||||
<c-r> *'ctrlp-fullregexp'*
|
<c-r> *'ctrlp-fullregexp'*
|
||||||
Toggle between the smart |regexp|/string mode (section 5.b) and full
|
Toggle between the string mode (section 5.a & b) and full |regexp| mode.
|
||||||
|regexp| mode.
|
|
||||||
(note: in full |regexp| mode, the prompt’s base is 'r>>' instead of '>>>')
|
(note: in full |regexp| mode, the prompt’s base is 'r>>' instead of '>>>')
|
||||||
|
|
||||||
See also |input-formats| and |g:ctrlp_regexp_search|.
|
See also |input-formats| and |g:ctrlp_regexp_search|.
|
||||||
@ -364,8 +363,8 @@ Formats for inputting in the prompt:
|
|||||||
|
|
||||||
a) Simple string. e.g. 'abc' is understood internally as 'a.\{-}b.\{-}c'
|
a) Simple string. e.g. 'abc' is understood internally as 'a.\{-}b.\{-}c'
|
||||||
|
|
||||||
b) Vim |regexp|. If the input string contains '*', '^', '$', '+' or '$', it’ll
|
b) Vim |regexp|. If the input string contains '*' or '|', it’ll be treated as
|
||||||
be treated as a Vim’s |regexp| |pattern| without any modification.
|
a Vim’s |regexp| |pattern| without any modification.
|
||||||
e.g. 'abc\d*efg' will be read as 'abc\d*efg'.
|
e.g. 'abc\d*efg' will be read as 'abc\d*efg'.
|
||||||
|
|
||||||
See also |ctrlp-fullregexp| and |g:ctrlp_regexp_search|.
|
See also |ctrlp-fullregexp| and |g:ctrlp_regexp_search|.
|
||||||
@ -397,8 +396,8 @@ Mercurial repository: https://bitbucket.org/kien/ctrlp.vim
|
|||||||
===============================================================================
|
===============================================================================
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
*ctrlp-update-2*
|
Before 2011/09/12
|
||||||
Update #2~
|
|
||||||
+ Ability to cycle through matched lines in the match window.
|
+ Ability to cycle through matched lines in the match window.
|
||||||
+ Extended the behavior of |g:ctrlp_persistent_input|
|
+ Extended the behavior of |g:ctrlp_persistent_input|
|
||||||
+ Extended the behavior of |:CtrlP|
|
+ Extended the behavior of |:CtrlP|
|
||||||
@ -412,8 +411,6 @@ Update #2~
|
|||||||
|:CtrlPCurFile|,
|
|:CtrlPCurFile|,
|
||||||
|:CtrlPRoot|
|
|:CtrlPRoot|
|
||||||
|
|
||||||
*ctrlp-update-1*
|
|
||||||
Update #1~
|
|
||||||
+ New feature: search in most recently used (MRU) files
|
+ New feature: search in most recently used (MRU) files
|
||||||
+ New mapping: <c-b>.
|
+ New mapping: <c-b>.
|
||||||
+ Extended the behavior of <c-f>.
|
+ Extended the behavior of <c-f>.
|
||||||
@ -423,5 +420,8 @@ Update #1~
|
|||||||
|g:ctrlp_mruf_include|
|
|g:ctrlp_mruf_include|
|
||||||
+ New command: |:CtrlPMRUFiles|
|
+ New command: |:CtrlPMRUFiles|
|
||||||
|
|
||||||
|
The updates are shown in reverse chronological order, from newest (top) to
|
||||||
|
oldest (bottom).
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
vim:nofen:et:ts=2:sw=2:sts=2
|
vim:nofen:et:ts=2:sw=2:sts=2
|
||||||
|
@ -11,7 +11,7 @@ Full path fuzzy __file__, __buffer__ and __MRU__ file finder for Vim.
|
|||||||
* Press `<c-p>` or run `:CtrlP` to invoke CtrlP.
|
* Press `<c-p>` or run `:CtrlP` to invoke CtrlP.
|
||||||
* Press `<c-f>` and `<c-b>` while CtrlP is open to switch between find file, find buffer, and find MRU file modes.
|
* Press `<c-f>` and `<c-b>` while CtrlP is open to switch between find file, find buffer, and find MRU file modes.
|
||||||
* Ever remember only a file’s name but not where it is? Press `<c-d>` while CtrlP is open to switch to filename only search.
|
* Ever remember only a file’s name but not where it is? Press `<c-d>` while CtrlP is open to switch to filename only search.
|
||||||
* Use `*` `?` `^` `+` or `|` in the prompt to submit the string as a Vim’s regexp pattern.
|
* Use `*` or `|` in the prompt to submit the string as a Vim’s regexp pattern.
|
||||||
* Or press `<c-r>` while CtrlP is open to switch to full regexp search mode.
|
* Or press `<c-r>` while CtrlP is open to switch to full regexp search mode.
|
||||||
* End the input string with a colon `:` followed with a number to jump to that line in the selected file.
|
* End the input string with a colon `:` followed with a number to jump to that line in the selected file.
|
||||||
e.g. `abc:45` to open the file matched the pattern and jump to line 45.
|
e.g. `abc:45` to open the file matched the pattern and jump to line 45.
|
||||||
|
Loading…
Reference in New Issue
Block a user