Add BufferTag extension

First version of buffertag.vim extension.
* Enable: `let g:ctrlp_extensions = ['buffertag']`
* Command: ':CtrlPBufTag'
* Options:
  + g:ctrlp_buftag_ctags_bin
  + g:ctrlp_buftag_systemenc
  + g:ctrlp_buftag_types
This commit is contained in:
Kien N 2011-12-21 18:58:08 +07:00
parent b22ebbee60
commit 7ccb62b28b
5 changed files with 276 additions and 15 deletions

View File

@ -2,7 +2,7 @@
" File: autoload/ctrlp.vim " File: autoload/ctrlp.vim
" Description: Fuzzy file, buffer, mru and tag finder. " Description: Fuzzy file, buffer, mru and tag finder.
" Author: Kien Nguyen <github.com/kien> " Author: Kien Nguyen <github.com/kien>
" Version: 1.6.4 " Version: 1.6.5
" ============================================================================= " =============================================================================
" Static variables {{{1 " Static variables {{{1
@ -327,7 +327,7 @@ fu! s:Update(str)
let oldstr = exists('s:savestr') ? s:savestr : '' let oldstr = exists('s:savestr') ? s:savestr : ''
let pats = s:SplitPattern(a:str) let pats = s:SplitPattern(a:str)
" Get the new string sans tail " Get the new string sans tail
let notail = substitute(a:str, ':\([^:]\|\\:\)*$', '', 'g') let notail = substitute(a:str, '\\\@<!:\([^:]\|\\:\)*$', '', '')
" Stop if the string's unchanged " Stop if the string's unchanged
if notail == oldstr && !empty(notail) && !exists('s:force') if notail == oldstr && !empty(notail) && !exists('s:force')
retu retu
@ -349,7 +349,8 @@ fu! s:BuildPrompt(upd, ...)
cal map(prt, 'escape(v:val, estr)') cal map(prt, 'escape(v:val, estr)')
let str = join(prt, '') let str = join(prt, '')
let lazy = empty(str) || exists('s:force') || !has('autocmd') ? 0 : s:lazy let lazy = empty(str) || exists('s:force') || !has('autocmd') ? 0 : s:lazy
if a:upd && ( s:matches || s:regexp || match(str, '[*|]') >= 0 ) && !lazy if a:upd && !lazy && ( s:matches || s:regexp
\ || match(str, '[*|]') >= 0 || match(str, '\\\:\([^:]\|\\:\)*$') >= 0 )
sil! cal s:Update(str) sil! cal s:Update(str)
en en
sil! cal ctrlp#statusline() sil! cal ctrlp#statusline()
@ -692,11 +693,11 @@ fu! ctrlp#acceptfile(mode, matchstr, ...)
" Switch to existing buffer or open new one " Switch to existing buffer or open new one
if exists('jmpb') && bufwinnr > 0 && md != 't' if exists('jmpb') && bufwinnr > 0 && md != 't'
exe bufwinnr.'winc w' exe bufwinnr.'winc w'
if j2l | cal s:j2l(j2l) | en if j2l | cal ctrlp#j2l(j2l) | en
elsei exists('jmpb') && buftab[0] elsei exists('jmpb') && buftab[0]
exe 'tabn' buftab[0] exe 'tabn' buftab[0]
exe buftab[1].'winc w' exe buftab[1].'winc w'
if j2l | cal s:j2l(j2l) | en if j2l | cal ctrlp#j2l(j2l) | en
el el
" Determine the command to use " Determine the command to use
let cmd = md == 't' || s:splitwin == 1 ? 'tabe' let cmd = md == 't' || s:splitwin == 1 ? 'tabe'
@ -1195,11 +1196,14 @@ endf
fu! s:sanstail(str) fu! s:sanstail(str)
" Restore the number of backslashes " Restore the number of backslashes
let str = substitute(a:str, '\\\\', '\', 'g') let [str, pat] = [substitute(a:str, '\\\\', '\', 'g'), '\([^:]\|\\:\)*$']
unl! s:optail unl! s:optail
if match(str, ':\([^:]\|\\:\)*$') >= 0 if match(str, '\\\@<!:'.pat) >= 0
let s:optail = matchstr(str, ':\zs\([^:]\|\\:\)*$') let s:optail = matchstr(str, ':\zs'.pat)
retu substitute(str, ':\([^:]\|\\:\)*$', '', 'g') retu substitute(str, ':'.pat, '', '')
en
if match(str, '\\\=:'.pat) >= 0
let str = substitute(str, '\\\=\ze:'.pat, '', '')
en en
retu str retu str
endf endf
@ -1229,7 +1233,7 @@ fu! s:openfile(cmd, filpath, ...)
cal ctrlp#msg("Operation can't be completed. Make sure filename is valid.") cal ctrlp#msg("Operation can't be completed. Make sure filename is valid.")
fina fina
if !empty(tail) if !empty(tail)
sil! norm! zOzz sil! norm! zvzz
en en
endt endt
endf endf
@ -1242,9 +1246,9 @@ fu! s:writecache(read_cache, cache_file)
en en
endf endf
fu! s:j2l(nr) fu! ctrlp#j2l(nr)
exe a:nr exe a:nr
sil! norm! zOzz sil! norm! zvzz
endf endf
fu! s:regexfilter(str) fu! s:regexfilter(str)

View File

@ -0,0 +1,215 @@
" =============================================================================
" File: autoload/ctrlp/buffertag.vim
" Description: Buffer Tag extension
" Maintainer: Kien Nguyen <github.com/kien>
" =============================================================================
" Init {{{1
if exists('g:loaded_ctrlp_buftag') && g:loaded_ctrlp_buftag
fini
en
let g:loaded_ctrlp_buftag = 1
let s:buftag_var = ['ctrlp#buffertag#init(s:crfile, s:crbufnr)',
\ 'ctrlp#buffertag#accept', 'buffer tags', 'bft']
let g:ctrlp_ext_vars = exists('g:ctrlp_ext_vars') && !empty(g:ctrlp_ext_vars)
\ ? add(g:ctrlp_ext_vars, s:buftag_var) : [s:buftag_var]
let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars)
fu! s:opts()
let opts = {
\ 'g:ctrlp_buftag_systemenc': ['s:enc', &enc],
\ 'g:ctrlp_buftag_ctags_bin': ['s:bin', ''],
\ 'g:ctrlp_buftag_types': ['s:usr_types', ''],
\ }
for [ke, va] in items(opts)
exe 'let' va[0] '=' string(exists(ke) ? eval(ke) : va[1])
endfo
endf
cal s:opts()
fu! s:bins()
let bins = [
\ 'ctags-exuberant',
\ 'exuberant-ctags',
\ 'exctags',
\ '/usr/local/bin/ctags',
\ '/opt/local/bin/ctags',
\ 'ctags',
\ 'ctags.exe',
\ 'tags',
\ ]
if empty(s:bin)
for bin in bins
if executable(bin)
let s:bin = bin
brea
en
endfo
el
let s:bin = expand(s:bin, 1)
en
endf
cal s:bins()
" Arguments {{{2
let s:types = {
\ 'asm' : '--language-force=asm --asm-types=dlmt',
\ 'aspperl' : '--language-force=asp --asp-types=fsv',
\ 'aspvbs' : '--language-force=asp --asp-types=fsv',
\ 'awk' : '--language-force=awk --awk-types=f',
\ 'beta' : '--language-force=beta --beta-types=fsv',
\ 'c' : '--language-force=c --c-types=dgsutvf',
\ 'cpp' : '--language-force=c++ --c++-types=nvdtcgsuf',
\ 'cs' : '--language-force=c# --c#-types=dtncEgsipm',
\ 'cobol' : '--language-force=cobol --cobol-types=dfgpPs',
\ 'eiffel' : '--language-force=eiffel --eiffel-types=cf',
\ 'erlang' : '--language-force=erlang --erlang-types=drmf',
\ 'expect' : '--language-force=tcl --tcl-types=cfp',
\ 'fortran' : '--language-force=fortran --fortran-types=pbceiklmntvfs',
\ 'html' : '--language-force=html --html-types=af',
\ 'java' : '--language-force=java --java-types=pcifm',
\ 'javascript': '--language-force=javascript --javascript-types=f',
\ 'lisp' : '--language-force=lisp --lisp-types=f',
\ 'lua' : '--language-force=lua --lua-types=f',
\ 'make' : '--language-force=make --make-types=m',
\ 'pascal' : '--language-force=pascal --pascal-types=fp',
\ 'perl' : '--language-force=perl --perl-types=clps',
\ 'php' : '--language-force=php --php-types=cdvf',
\ 'python' : '--language-force=python --python-types=cmf',
\ 'rexx' : '--language-force=rexx --rexx-types=s',
\ 'ruby' : '--language-force=ruby --ruby-types=cfFm',
\ 'scheme' : '--language-force=scheme --scheme-types=sf',
\ 'sh' : '--language-force=sh --sh-types=f',
\ 'csh' : '--language-force=sh --sh-types=f',
\ 'zsh' : '--language-force=sh --sh-types=f',
\ 'slang' : '--language-force=slang --slang-types=nf',
\ 'sml' : '--language-force=sml --sml-types=ecsrtvf',
\ 'sql' : '--language-force=sql --sql-types=cFPrstTvfp',
\ 'tcl' : '--language-force=tcl --tcl-types=cfmp',
\ 'vera' : '--language-force=vera --vera-types=cdefgmpPtTvx',
\ 'verilog' : '--language-force=verilog --verilog-types=mcPertwpvf',
\ 'vim' : '--language-force=vim --vim-types=avf',
\ 'yacc' : '--language-force=yacc --yacc-types=l',
\ }
if executable('jsctags')
cal extend(s:types, { 'javascript': { 'args': '-f -', 'bin': 'jsctags' } })
en
if type(s:usr_types) == 4
cal extend(s:types, s:usr_types)
en
" Utilities {{{1
fu! s:validfile(fname, ftype)
if ( !empty(a:fname) || !empty(a:ftype) ) && filereadable(a:fname)
\ && index(keys(s:types), a:ftype) >= 0 | retu 1 | en
retu 0
endf
fu! s:exectags(cmd)
if exists('+ssl')
let [ssl, &ssl] = [&ssl, 0]
en
if &sh =~ 'cmd\.exe'
let [sxq, &sxq, shcf, &shcf] = [&sxq, '"', &shcf, '/s /c']
en
let output = system(a:cmd)
if &sh =~ 'cmd\.exe'
let [&sxq, &shcf] = [sxq, shcf]
en
if exists('+ssl')
let &ssl = ssl
en
retu output
endf
fu! s:exectagsonfile(fname, ftype)
let args = '-f - --sort=no --excmd=pattern --fields=nKs '
if type(s:types[a:ftype]) == 1
let args .= s:types[a:ftype]
let bin = s:bin
elsei type(s:types[a:ftype]) == 4
let args = s:types[a:ftype]['args']
let bin = expand(s:types[a:ftype]['bin'], 1)
en
if empty(bin) | retu '' | en
let cmd = s:esctagscmd(bin, args, a:fname)
if empty(cmd) | retu '' | en
let output = s:exectags(cmd)
if v:shell_error || output =~ 'Warning: cannot open' | retu '' | en
retu output
endf
fu! s:esctagscmd(bin, args, ...)
if exists('+ssl')
let [ssl, &ssl] = [&ssl, 0]
en
let fname = a:0 == 1 ? shellescape(a:1) : ''
let cmd = shellescape(a:bin).' '.a:args.' '.fname
if exists('+ssl')
let &ssl = ssl
en
if has('iconv')
let last = s:enc != &enc ? s:enc : !empty($LANG) ? $LANG : &enc
let cmd = call('iconv', [cmd, &encoding, last])
en
if empty(cmd)
cal ctrlp#msg('Encoding conversion failed!')
en
retu cmd
endf
fu! s:process(fname, ftype)
if !s:validfile(a:fname, a:ftype) | retu [] | endif
let ftime = getftime(a:fname)
if has_key(g:ctrlp_buftags, a:fname)
\ && g:ctrlp_buftags[a:fname]['time'] >= ftime
let data = g:ctrlp_buftags[a:fname]['data']
el
let data = s:exectagsonfile(a:fname, a:ftype)
let cache = { a:fname : { 'time': ftime, 'data': data } }
cal extend(g:ctrlp_buftags, cache)
en
let [raw, lines] = [split(data, '\n\+'), []]
for line in raw | if len(split(line, ';"')) == 2
cal add(lines, s:parseline(line))
en | endfo
retu lines
endf
fu! s:parseline(line)
let eval = '\v^([^\t]+)\t(.+)\t\/\^(.+)\$\/\;\"\t(.+)\tline(no)?\:(\d+)'
let vals = matchlist(a:line, eval)
if empty(vals) | retu '' | en
retu vals[1].' '.vals[4].'|'.vals[6].'| '.vals[3]
endf
" Public {{{1
fu! ctrlp#buffertag#init(fname, bufnr)
let s:fname = a:fname
let ftype = get(split(getbufvar(a:bufnr, '&filetype'), '\.'), 0, '')
sy match CtrlPTabExtra '\zs\t.*\ze$'
hi link CtrlPTabExtra Comment
retu s:process(a:fname, ftype)
endf
fu! ctrlp#buffertag#accept(mode, str)
cal ctrlp#exit()
if a:mode == 't'
exe 'tabe' ctrlp#fnesc(s:fname)
elsei a:mode == 'h'
sp
elsei a:mode == 'v'
vs
en
cal ctrlp#j2l(str2nr(matchstr(a:str, '^[^\t]\+\t\+[^\t|]\+|\zs\d\+\ze|')))
endf
fu! ctrlp#buffertag#id()
retu s:id
endf
"}}}
" vim:fen:fdm=marker:fmr={{{,}}}:fdl=0:fdc=1:ts=2:sw=2:sts=2

View File

@ -43,7 +43,7 @@ fu! ctrlp#quickfix#accept(mode, str)
cat cat
cal ctrlp#msg("Invalid command or argument.") cal ctrlp#msg("Invalid command or argument.")
fina fina
cal cursor(items[2], items[3]) | sil! norm! zOzz cal cursor(items[2], items[3]) | sil! norm! zvzz
endt endt
endf endf

View File

@ -1,4 +1,4 @@
*ctrlp.txt* Fuzzy file, buffer, mru and tag finder. v1.6.4 *ctrlp.txt* Fuzzy file, buffer, mru and tag finder. v1.6.5
*CtrlP* *ControlP* *'ctrlp'* *'ctrl-p'* *CtrlP* *ControlP* *'ctrlp'* *'ctrl-p'*
=============================================================================== ===============================================================================
# # # #
@ -516,7 +516,7 @@ g) Submit ? to open this help file.
Extensions are optional. To enable an extension, add its name to the variable Extensions are optional. To enable an extension, add its name to the variable
g:ctrlp_extensions: > g:ctrlp_extensions: >
let g:ctrlp_extensions = ['tag', 'quickfix', 'dir'] let g:ctrlp_extensions = ['tag', 'buffertag', 'quickfix', 'dir']
< <
The order of the items will be the order they appear on the statusline and when The order of the items will be the order they appear on the statusline and when
using <c-f>, <c-b>. using <c-f>, <c-b>.
@ -531,6 +531,13 @@ Available extensions:~
definition. Use the Vims option |'tags'| to specify the names and the definition. Use the Vims option |'tags'| to specify the names and the
locations of the tags file(s). Example: `set tags+=tags/help,doc/tags` locations of the tags file(s). Example: `set tags+=tags/help,doc/tags`
*:CtrlPBufTag*
* Buffer Tag mode:~
- Name: 'buffertag'
- Command: ':CtrlPBufTag'
- Search for a tag within the current buffer and jump to the definition.
Requires |exuberant_ctags|.
*:CtrlPQuickfix* *:CtrlPQuickfix*
* Quickfix mode:~ * Quickfix mode:~
- Name: 'quickfix' - Name: 'quickfix'
@ -549,6 +556,34 @@ Available extensions:~
+ <c-x> change the global working directory to |CtrlP|s current local + <c-x> change the global working directory to |CtrlP|s current local
working directory (exit). working directory (exit).
-------------------------------------------------------------------------------
Buffer Tag mode options:~
*'g:ctrlp_buftag_ctags_bin'*
If ctags isnt in your $PATH, use this to set its location: >
let g:ctrlp_buftag_ctags_bin = ''
<
*'g:ctrlp_buftag_systemenc'*
Match this with your OSs encoding (not Vims). The default value mirrors Vims
global |'encoding'| option: >
let g:ctrlp_buftag_systemenc = &encoding
<
*'g:ctrlp_buftag_types'*
Use this to set the arguments for ctags, jsctags... for a given filetype: >
let g:ctrlp_buftag_types = ''
<
Examples: >
let g:ctrlp_buftag_types = {
\ 'erlang' : '--language-force=erlang --erlang-types=drmf',
\ 'javascript' : {
\ 'bin': 'jsctags',
\ 'args': '-f -',
\ },
\ }
<
=============================================================================== ===============================================================================
EXTENDING *ctrlp-extending* EXTENDING *ctrlp-extending*
@ -599,6 +634,8 @@ Special thanks:~
=============================================================================== ===============================================================================
CHANGELOG *ctrlp-changelog* CHANGELOG *ctrlp-changelog*
+ New feature: Buffer Tag extension.
+ New command: |:CtrlPBufTag|.
+ New options: |g:ctrlp_cmd|, + New options: |g:ctrlp_cmd|,
|g:ctrlp_custom_ignore| |g:ctrlp_custom_ignore|

View File

@ -43,3 +43,8 @@ en
if index(g:ctrlp_extensions, 'dir') >= 0 if index(g:ctrlp_extensions, 'dir') >= 0
let g:ctrlp_alldirs = [] | com! CtrlPDir cal ctrlp#init(ctrlp#dir#id()) let g:ctrlp_alldirs = [] | com! CtrlPDir cal ctrlp#init(ctrlp#dir#id())
en en
if index(g:ctrlp_extensions, 'buffertag') >= 0
let g:ctrlp_buftags = {}
com! CtrlPBufTag cal ctrlp#init(ctrlp#buffertag#id())
en