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
" Description: Fuzzy file, buffer, mru and tag finder.
" Author: Kien Nguyen <github.com/kien>
" Version: 1.6.4
" Version: 1.6.5
" =============================================================================
" Static variables {{{1
@ -327,7 +327,7 @@ fu! s:Update(str)
let oldstr = exists('s:savestr') ? s:savestr : ''
let pats = s:SplitPattern(a:str)
" Get the new string sans tail
let notail = substitute(a:str, ':\([^:]\|\\:\)*$', '', 'g')
let notail = substitute(a:str, '\\\@<!:\([^:]\|\\:\)*$', '', '')
" Stop if the string's unchanged
if notail == oldstr && !empty(notail) && !exists('s:force')
retu
@ -349,7 +349,8 @@ fu! s:BuildPrompt(upd, ...)
cal map(prt, 'escape(v:val, estr)')
let str = join(prt, '')
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)
en
sil! cal ctrlp#statusline()
@ -692,11 +693,11 @@ fu! ctrlp#acceptfile(mode, matchstr, ...)
" Switch to existing buffer or open new one
if exists('jmpb') && bufwinnr > 0 && md != 't'
exe bufwinnr.'winc w'
if j2l | cal s:j2l(j2l) | en
if j2l | cal ctrlp#j2l(j2l) | en
elsei exists('jmpb') && buftab[0]
exe 'tabn' buftab[0]
exe buftab[1].'winc w'
if j2l | cal s:j2l(j2l) | en
if j2l | cal ctrlp#j2l(j2l) | en
el
" Determine the command to use
let cmd = md == 't' || s:splitwin == 1 ? 'tabe'
@ -1195,11 +1196,14 @@ endf
fu! s:sanstail(str)
" Restore the number of backslashes
let str = substitute(a:str, '\\\\', '\', 'g')
let [str, pat] = [substitute(a:str, '\\\\', '\', 'g'), '\([^:]\|\\:\)*$']
unl! s:optail
if match(str, ':\([^:]\|\\:\)*$') >= 0
let s:optail = matchstr(str, ':\zs\([^:]\|\\:\)*$')
retu substitute(str, ':\([^:]\|\\:\)*$', '', 'g')
if match(str, '\\\@<!:'.pat) >= 0
let s:optail = matchstr(str, ':\zs'.pat)
retu substitute(str, ':'.pat, '', '')
en
if match(str, '\\\=:'.pat) >= 0
let str = substitute(str, '\\\=\ze:'.pat, '', '')
en
retu str
endf
@ -1229,7 +1233,7 @@ fu! s:openfile(cmd, filpath, ...)
cal ctrlp#msg("Operation can't be completed. Make sure filename is valid.")
fina
if !empty(tail)
sil! norm! zOzz
sil! norm! zvzz
en
endt
endf
@ -1242,9 +1246,9 @@ fu! s:writecache(read_cache, cache_file)
en
endf
fu! s:j2l(nr)
fu! ctrlp#j2l(nr)
exe a:nr
sil! norm! zOzz
sil! norm! zvzz
endf
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
cal ctrlp#msg("Invalid command or argument.")
fina
cal cursor(items[2], items[3]) | sil! norm! zOzz
cal cursor(items[2], items[3]) | sil! norm! zvzz
endt
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'*
===============================================================================
# #
@ -516,7 +516,7 @@ g) Submit ? to open this help file.
Extensions are optional. To enable an extension, add its name to the variable
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
using <c-f>, <c-b>.
@ -531,6 +531,13 @@ Available extensions:~
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`
*: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*
* Quickfix mode:~
- Name: 'quickfix'
@ -549,6 +556,34 @@ Available extensions:~
+ <c-x> change the global working directory to |CtrlP|s current local
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*
@ -599,6 +634,8 @@ Special thanks:~
===============================================================================
CHANGELOG *ctrlp-changelog*
+ New feature: Buffer Tag extension.
+ New command: |:CtrlPBufTag|.
+ New options: |g:ctrlp_cmd|,
|g:ctrlp_custom_ignore|

View File

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