Support jsctags and other compatible programs

This commit is contained in:
Jan Larres 2011-04-25 19:32:19 +12:00
parent b25ab098da
commit b374ff5eab
2 changed files with 93 additions and 39 deletions

View File

@ -11,6 +11,7 @@ Contents *tagbar* *tagbar-contents*
1. Intro ........................... |tagbar-intro|
Pseudo-tags ................... |tagbar-pseudotags|
Supported features ............ |tagbar-features|
Other ctags-compatible programs |tagbar-other|
2. Requirements .................... |tagbar-requirements|
3. Installation .................... |tagbar-installation|
4. Usage ........................... |tagbar-usage|
@ -102,6 +103,16 @@ The following features are supported by Tagbar:
Tex, Vera, Verilog, VHDL, Vim and YACC.
- Can be extended to support arbitrary new types.
------------------------------------------------------------------------------
OTHER CTAGS-COMPATIBLE PROGRAMS *tagbar-other*
Tagbar theoretically also supports filetype-specific programs that can output
tag information that is compatible with ctags. However due to potential
incompatibilities this may not always completely work. Tagbar has been tested
with doctorjs/jsctags and will use that if present, other programs require
some configuration (see |tagbar-extend|). If a program does not work even with
correct configuration please contact me.
==============================================================================
2. Requirements *tagbar-requirements*
@ -119,8 +130,8 @@ The following requirements have to be met in order to be able to use tagbar:
Tagbar will work on any platform that ctags runs on -- this includes
UNIX derivatives, Mac OS X and Windows. Note that other versions like
GNU ctags will not work.
Tagbar generates the tag information by itself and doesn't need already
existing tag files.
Tagbar generates the tag information by itself and doesn't need (or use)
already existing tag files.
- File type detection must be turned on in vim. This can be done with the
following command in your vimrc:
>
@ -499,8 +510,8 @@ kinds: A list of the "language kinds" that should be listed in Tagbar,
< would list all the function definitions in a file under the header
"functions" and fold them.
sro: The scope resolution operator. For example, in C++ it is "::" and
in Java it is ".". When in doubt run ctags as shown above and look
at the output.
in Java it is ".". If in doubt run ctags as shown above and check
the output.
kind2scope: A dictionary describing the mapping of tag kinds (in their
one-character representation) to the scopes their children will
appear in, for example classes, structs etc.
@ -549,8 +560,16 @@ deffile: The path to a file with additional ctags definitions (see the
< Then the "deffile" entry would look like this to allow for the
plugin to be installed in an arbitray location (for example
with pathogen): >
'deffile' : expand('<sfile>:p:h:h') . '/ctags/mylang.cnf'
<
ctagsbin: The path to a filetype-specific ctags-compatible program like
{optional} jsctags. Set it in the same way as |g:tagbar_ctags_bin|. jsctags is
used automatically if found in your $PATH and does not have to be
set in that case.
ctagsargs: The arguments to be passed to the filetype-specific ctags program
{optional} (without the filename). Not used for the normal ctags program.
You then have to assign this dictionary to a variable with the name
>

View File

@ -411,15 +411,33 @@ function! s:InitTypes()
" JavaScript is weird -- it does have scopes, but ctags doesn't seem to
" properly generate the information for them, instead it simply uses the
" complete name. So ctags has to be fixed before I can do anything here.
" Alternatively jsctags/doctorjs will be used if available.
let type_javascript = {}
let type_javascript.ctagstype = 'javascript'
let type_javascript.kinds = [
\ {'short' : 'v', 'long' : 'global variables', 'fold' : 0},
\ {'short' : 'c', 'long' : 'classes', 'fold' : 0},
\ {'short' : 'p', 'long' : 'properties', 'fold' : 0},
\ {'short' : 'm', 'long' : 'methods', 'fold' : 0},
\ {'short' : 'f', 'long' : 'functions', 'fold' : 0}
\ ]
if executable('jsctags')
let type_javascript.kinds = [
\ {'short' : 'v', 'long' : 'variables', 'fold' : 0},
\ {'short' : 'f', 'long' : 'functions', 'fold' : 0}
\ ]
let type_javascript.sro = '.'
let type_javascript.kind2scope = {
\ 'v' : 'namespace',
\ 'f' : 'namespace'
\ }
let type_javascript.scope2kind = {
\ 'namespace' : 'v'
\ }
let type_javascript.ctagsbin = 'jsctags'
let type_javascript.ctagsargs = '-f -'
else
let type_javascript.kinds = [
\ {'short' : 'v', 'long' : 'global variables', 'fold' : 0},
\ {'short' : 'c', 'long' : 'classes', 'fold' : 0},
\ {'short' : 'p', 'long' : 'properties', 'fold' : 0},
\ {'short' : 'm', 'long' : 'methods', 'fold' : 0},
\ {'short' : 'f', 'long' : 'functions', 'fold' : 0}
\ ]
endif
let s:known_types.javascript = type_javascript
" Lisp {{{3
let type_lisp = {}
@ -1009,12 +1027,14 @@ endfunction
" s:NormalTag.str() {{{3
function! s:NormalTag.str(fileinfo, typeinfo) dict
let suffix = get(self.fields, 'signature', '')
if has_key(a:typeinfo, 'kind2scope') &&
\ has_key(a:typeinfo.kind2scope, self.fields.kind)
if has_key(self.fields, 'type')
let suffix .= ' : ' . self.fields.type
elseif has_key(a:typeinfo, 'kind2scope') &&
\ has_key(a:typeinfo.kind2scope, self.fields.kind)
let suffix .= ' : ' . a:typeinfo.kind2scope[self.fields.kind]
endif
return self._getPrefix(a:fileinfo, a:typeinfo) . self.name . suffix
return self._getPrefix(a:fileinfo, a:typeinfo) . self.name . suffix . "\n"
endfunction
" s:NormalTag.getPrototype() {{{3
@ -1404,32 +1424,42 @@ function! s:ProcessFile(fname, ftype)
let typeinfo = s:known_types[a:ftype]
let ctags_args = ' -f - '
let ctags_args .= ' --format=2 '
let ctags_args .= ' --excmd=pattern '
let ctags_args .= ' --fields=nksSaz '
let ctags_args .= ' --extra= '
let ctags_args .= ' --sort=yes '
if has_key(typeinfo, 'ctagsargs')
let ctags_args = ' ' . typeinfo.ctagsargs . ' '
else
let ctags_args = ' -f - '
let ctags_args .= ' --format=2 '
let ctags_args .= ' --excmd=pattern '
let ctags_args .= ' --fields=nksSa '
let ctags_args .= ' --extra= '
let ctags_args .= ' --sort=yes '
" Include extra type definitions
if has_key(typeinfo, 'deffile')
let ctags_args .= ' --options=' . typeinfo.deffile . ' '
" Include extra type definitions
if has_key(typeinfo, 'deffile')
let ctags_args .= ' --options=' . typeinfo.deffile . ' '
endif
let ctags_type = typeinfo.ctagstype
let ctags_kinds = ''
for kind in typeinfo.kinds
let ctags_kinds .= kind.short
endfor
let ctags_args .= ' --language-force=' . ctags_type .
\ ' --' . ctags_type . '-kinds=' . ctags_kinds . ' '
endif
let ctags_type = typeinfo.ctagstype
let ctags_kinds = ''
for kind in typeinfo.kinds
let ctags_kinds .= kind.short
endfor
let ctags_args .= ' --language-force=' . ctags_type .
\ ' --' . ctags_type . '-kinds=' . ctags_kinds . ' '
if has_key(typeinfo, 'ctagsbin')
let ctags_bin = expand(typeinfo.ctagsbin)
else
let ctags_bin = g:tagbar_ctags_bin
endif
if has('win32') || has('win64')
let ctags_bin = fnamemodify(g:tagbar_ctags_bin, ':8')
let ctags_bin = fnamemodify(ctags_bin, ':8')
else
let ctags_bin = shellescape(g:tagbar_ctags_bin)
let ctags_bin = shellescape(ctags_bin)
endif
let ctags_cmd = ctags_bin . ctags_args . shellescape(a:fname)
let ctags_output = system(ctags_cmd)
@ -1550,6 +1580,7 @@ function! s:ParseTagline(part1, part2, typeinfo, fileinfo)
let taginfo.prototype = prototype
let fields = split(a:part2, '\t')
let taginfo.fields.kind = remove(fields, 0)
for field in fields
" can't use split() since the value can contain ':'
let delimit = stridx(field, ':')
@ -1557,6 +1588,10 @@ function! s:ParseTagline(part1, part2, typeinfo, fileinfo)
let val = strpart(field, delimit + 1)
let taginfo.fields[key] = val
endfor
" Needed for jsctags
if has_key(taginfo.fields, 'lineno')
let taginfo.fields.line = taginfo.fields.lineno
endif
" Make some information easier accessible
if has_key(a:typeinfo, 'scope2kind')
@ -1917,7 +1952,7 @@ endfunction
" s:PrintKinds() {{{2
function! s:PrintKinds(typeinfo, fileinfo)
let first_kind = 1
let first_tag = 1
for kind in a:typeinfo.kinds
let curtags = filter(copy(a:fileinfo.tags),
@ -1931,7 +1966,7 @@ function! s:PrintKinds(typeinfo, fileinfo)
\ has_key(a:typeinfo.kind2scope, kind.short)
" Scoped tags
for tag in curtags
if g:tagbar_compact && first_kind && s:short_help
if g:tagbar_compact && first_tag && s:short_help
silent 0put =tag.str(a:fileinfo, a:typeinfo)
else
silent put =tag.str(a:fileinfo, a:typeinfo)
@ -1953,8 +1988,8 @@ function! s:PrintKinds(typeinfo, fileinfo)
silent put _
endif
let first_tag = 0
endfor
let first_kind = 0
else
" Non-scoped tags
let kindtag = curtags[0].parent
@ -1965,7 +2000,7 @@ function! s:PrintKinds(typeinfo, fileinfo)
let foldmarker = s:icon_open
endif
if g:tagbar_compact && first_kind && s:short_help
if g:tagbar_compact && first_tag && s:short_help
silent 0put =foldmarker . ' ' . kind.long
else
silent put =foldmarker . ' ' . kind.long
@ -1993,7 +2028,7 @@ function! s:PrintKinds(typeinfo, fileinfo)
silent put _
endif
let first_kind = 0
let first_tag = 0
endif
endfor
endfunction