" ============================================================================ " File: tagbar.vim " Description: List the current file's tags in a sidebar, ordered by class etc " Author: Jan Larres " Licence: Vim licence " Website: http://majutsushi.github.com/tagbar/ " Version: 2.7 " Note: This plugin was heavily inspired by the 'Taglist' plugin by " Yegappan Lakshmanan and uses a small amount of code from it. " " Original taglist copyright notice: " Permission is hereby granted to use and distribute this code, " with or without modifications, provided that this copyright " notice is copied with it. Like anything else that's free, " taglist.vim is provided *as is* and comes with no warranty of " any kind, either expressed or implied. In no event will the " copyright holder be liable for any damamges resulting from the " use of this software. " ============================================================================ scriptencoding utf-8 " Initialization {{{1 " If another plugin calls an autoloaded Tagbar function on startup before the " plugin/tagbar.vim file got loaded, load it explicitly if exists(':Tagbar') == 0 runtime plugin/tagbar.vim endif if exists(':Tagbar') == 0 echomsg 'Tagbar: Could not load plugin code, check your runtimepath!' finish endif " Basic init {{{2 redir => s:ftype_out silent filetype redir END if s:ftype_out !~# 'detection:ON' echomsg 'Tagbar: Filetype detection is turned off, skipping plugin' unlet s:ftype_out finish endif unlet s:ftype_out let g:tagbar#icon_closed = g:tagbar_iconchars[0] let g:tagbar#icon_open = g:tagbar_iconchars[1] let s:type_init_done = 0 let s:autocommands_done = 0 let s:statusline_in_use = 0 let s:init_done = 0 " 0: not checked yet; 1: checked and found; 2: checked and not found let s:checked_ctags = 0 let s:checked_ctags_types = 0 let s:ctags_is_uctags = 0 let s:new_window = 1 let s:is_maximized = 0 let s:winrestcmd = '' let s:short_help = 1 let s:nearby_disabled = 0 let s:paused = 0 let s:pwin_by_tagbar = 0 let s:buffer_seqno = 0 let s:vim_quitting = 0 let s:last_alt_bufnr = -1 let s:window_expanded = 0 let s:expand_bufnr = -1 let s:window_pos = { \ 'pre' : { 'x' : 0, 'y' : 0 }, \ 'post' : { 'x' : 0, 'y' : 0 } \} let s:delayed_update_files = [] let g:loaded_tagbar = 1 let s:last_highlight_tline = 0 let s:warnings = { \ 'type': [], \ 'encoding': 0 \ } " s:Init() {{{2 function! s:Init(silent) abort if s:checked_ctags == 2 && a:silent return 0 elseif s:checked_ctags != 1 if !s:CheckForExCtags(a:silent) return 0 endif endif if !s:type_init_done call s:InitTypes() endif if !s:autocommands_done call s:CreateAutocommands() call s:AutoUpdate(fnamemodify(expand('%'), ':p'), 0) endif let s:init_done = 1 return 1 endfunction " s:InitTypes() {{{2 function! s:InitTypes() abort call tagbar#debug#log('Initializing types') let supported_types = s:GetSupportedFiletypes() if s:ctags_is_uctags let s:known_types = tagbar#types#uctags#init(supported_types) else let s:known_types = tagbar#types#ctags#init(supported_types) endif " Use jsctags/doctorjs if available let jsctags = s:CheckFTCtags('jsctags', 'javascript') if jsctags != '' call tagbar#debug#log('Detected jsctags, overriding typedef') let type_javascript = tagbar#prototypes#typeinfo#new() let type_javascript.ctagstype = 'javascript' let type_javascript.kinds = [ \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 0}, \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1} \ ] let type_javascript.sro = '.' let type_javascript.kind2scope = { \ 'v' : 'namespace', \ 'f' : 'namespace' \ } let type_javascript.scope2kind = { \ 'namespace' : 'f' \ } let type_javascript.ctagsbin = jsctags let type_javascript.ctagsargs = '-f -' let type_javascript.ftype = 'javascript' call type_javascript.createKinddict() let s:known_types.javascript = type_javascript endif call s:LoadUserTypeDefs() " Add an 'unknown' kind to the types for pseudotags that we can't " determine the correct kind for since they don't have any children that " are not pseudotags and that therefore don't provide scope information for typeinfo in values(s:known_types) if has_key(typeinfo, 'kind2scope') let unknown_kind = \ {'short' : '?', 'long' : 'unknown', 'fold' : 0, 'stl' : 1} " Check for existence first since some types exist under more than " one name if index(typeinfo.kinds, unknown_kind) == -1 call add(typeinfo.kinds, unknown_kind) endif let typeinfo.kind2scope['?'] = 'unknown' endif endfor let s:type_init_done = 1 endfunction " s:LoadUserTypeDefs() {{{2 function! s:LoadUserTypeDefs(...) abort if a:0 > 0 let type = a:1 let defdict = {} let defdict[type] = g:tagbar_type_{type} else let defdict = tagbar#getusertypes() endif let transformed = {} for [type, def] in items(defdict) let transformed[type] = s:TransformUserTypeDef(def) let transformed[type].ftype = type endfor for [key, value] in items(transformed) call tagbar#debug#log("Initializing user type '" . key . "'") if !has_key(s:known_types, key) || get(value, 'replace', 0) let s:known_types[key] = tagbar#prototypes#typeinfo#new(value) else call extend(s:known_types[key], value) endif call s:known_types[key].createKinddict() endfor endfunction " s:TransformUserTypeDef() {{{2 " Transform the user definitions into the internal format function! s:TransformUserTypeDef(def) abort let newdef = copy(a:def) if has_key(a:def, 'kinds') let newdef.kinds = [] let kinds = a:def.kinds for kind in kinds let kindlist = split(kind, ':') let kinddict = {'short' : kindlist[0], 'long' : kindlist[1]} let kinddict.fold = get(kindlist, 2, 0) let kinddict.stl = get(kindlist, 3, 1) call add(newdef.kinds, kinddict) endfor endif " If the user only specified one of kind2scope and scope2kind then use it " to generate the respective other if has_key(a:def, 'kind2scope') && !has_key(a:def, 'scope2kind') let newdef.scope2kind = {} for [key, value] in items(a:def.kind2scope) let newdef.scope2kind[value] = key endfor elseif has_key(a:def, 'scope2kind') && !has_key(a:def, 'kind2scope') let newdef.kind2scope = {} for [key, value] in items(a:def.scope2kind) let newdef.kind2scope[value] = key endfor endif return newdef endfunction " s:RestoreSession() {{{2 " Properly restore Tagbar after a session got loaded function! s:RestoreSession() abort if s:init_done call tagbar#debug#log('Tagbar already initialized; not restoring session') return endif call tagbar#debug#log('Restoring session') let curfile = fnamemodify(bufname('%'), ':p') let tagbarwinnr = bufwinnr(s:TagbarBufName()) if tagbarwinnr == -1 " Tagbar wasn't open in the saved session, nothing to do return endif let in_tagbar = 1 if winnr() != tagbarwinnr call s:goto_win(tagbarwinnr, 1) let in_tagbar = 0 endif let s:last_autofocus = 0 call s:Init(0) call s:InitWindow(g:tagbar_autoclose) call s:AutoUpdate(curfile, 0) if !in_tagbar call s:goto_win('p') endif endfunction " s:MapKeys() {{{2 function! s:MapKeys() abort call tagbar#debug#log('Mapping keys') nnoremap