diff options
Diffstat (limited to '.vim/plugin/taglist.vim')
-rw-r--r-- | .vim/plugin/taglist.vim | 4546 |
1 files changed, 4546 insertions, 0 deletions
diff --git a/.vim/plugin/taglist.vim b/.vim/plugin/taglist.vim new file mode 100644 index 0000000..59901f6 --- /dev/null +++ b/.vim/plugin/taglist.vim @@ -0,0 +1,4546 @@ +" File: taglist.vim +" Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) +" Version: 4.5 +" Last Modified: September 21, 2007 +" Copyright: Copyright (C) 2002-2007 Yegappan Lakshmanan +" 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. +" +" The "Tag List" plugin is a source code browser plugin for Vim and provides +" an overview of the structure of the programming language files and allows +" you to efficiently browse through source code files for different +" programming languages. You can visit the taglist plugin home page for more +" information: +" +" http://vim-taglist.sourceforge.net +" +" You can subscribe to the taglist mailing list to post your questions +" or suggestions for improvement or to report bugs. Visit the following +" page for subscribing to the mailing list: +" +" http://groups.yahoo.com/group/taglist/ +" +" For more information about using this plugin, after installing the +" taglist plugin, use the ":help taglist" command. +" +" Installation +" ------------ +" 1. Download the taglist.zip file and unzip the files to the $HOME/.vim +" or the $HOME/vimfiles or the $VIM/vimfiles directory. This should +" unzip the following two files (the directory structure should be +" preserved): +" +" plugin/taglist.vim - main taglist plugin file +" doc/taglist.txt - documentation (help) file +" +" Refer to the 'add-plugin', 'add-global-plugin' and 'runtimepath' +" Vim help pages for more details about installing Vim plugins. +" 2. Change to the $HOME/.vim/doc or $HOME/vimfiles/doc or +" $VIM/vimfiles/doc directory, start Vim and run the ":helptags ." +" command to process the taglist help file. +" 3. If the exuberant ctags utility is not present in your PATH, then set the +" Tlist_Ctags_Cmd variable to point to the location of the exuberant ctags +" utility (not to the directory) in the .vimrc file. +" 4. If you are running a terminal/console version of Vim and the +" terminal doesn't support changing the window width then set the +" 'Tlist_Inc_Winwidth' variable to 0 in the .vimrc file. +" 5. Restart Vim. +" 6. You can now use the ":TlistToggle" command to open/close the taglist +" window. You can use the ":help taglist" command to get more +" information about using the taglist plugin. +" +" ****************** Do not modify after this line ************************ + +" Line continuation used here +let s:cpo_save = &cpo +set cpo&vim + +if !exists('loaded_taglist') + " First time loading the taglist plugin + " + " To speed up the loading of Vim, the taglist plugin uses autoload + " mechanism to load the taglist functions. + " Only define the configuration variables, user commands and some + " auto-commands and finish sourcing the file + + " The taglist plugin requires the built-in Vim system() function. If this + " function is not available, then don't load the plugin. + if !exists('*system') + echomsg 'Taglist: Vim system() built-in function is not available. ' . + \ 'Plugin is not loaded.' + let loaded_taglist = 'no' + let &cpo = s:cpo_save + finish + endif + + " Location of the exuberant ctags tool + if !exists('Tlist_Ctags_Cmd') + if executable('exuberant-ctags') + " On Debian Linux, exuberant ctags is installed + " as exuberant-ctags + let Tlist_Ctags_Cmd = 'exuberant-ctags' + elseif executable('exctags') + " On Free-BSD, exuberant ctags is installed as exctags + let Tlist_Ctags_Cmd = 'exctags' + elseif executable('ctags') + let Tlist_Ctags_Cmd = 'ctags' + elseif executable('ctags.exe') + let Tlist_Ctags_Cmd = 'ctags.exe' + elseif executable('tags') + let Tlist_Ctags_Cmd = 'tags' + else + echomsg 'Taglist: Exuberant ctags (http://ctags.sf.net) ' . + \ 'not found in PATH. Plugin is not loaded.' + " Skip loading the plugin + let loaded_taglist = 'no' + let &cpo = s:cpo_save + finish + endif + endif + + + " Automatically open the taglist window on Vim startup + if !exists('Tlist_Auto_Open') + let Tlist_Auto_Open = 0 + endif + + " When the taglist window is toggle opened, move the cursor to the + " taglist window + if !exists('Tlist_GainFocus_On_ToggleOpen') + let Tlist_GainFocus_On_ToggleOpen = 0 + endif + + " Process files even when the taglist window is not open + if !exists('Tlist_Process_File_Always') + let Tlist_Process_File_Always = 0 + endif + + if !exists('Tlist_Show_Menu') + let Tlist_Show_Menu = 0 + endif + + " Tag listing sort type - 'name' or 'order' + if !exists('Tlist_Sort_Type') + let Tlist_Sort_Type = 'order' + endif + + " Tag listing window split (horizontal/vertical) control + if !exists('Tlist_Use_Horiz_Window') + let Tlist_Use_Horiz_Window = 0 + endif + + " Open the vertically split taglist window on the left or on the right + " side. This setting is relevant only if Tlist_Use_Horiz_Window is set to + " zero (i.e. only for vertically split windows) + if !exists('Tlist_Use_Right_Window') + let Tlist_Use_Right_Window = 0 + endif + + " Increase Vim window width to display vertically split taglist window. + " For MS-Windows version of Vim running in a MS-DOS window, this must be + " set to 0 otherwise the system may hang due to a Vim limitation. + if !exists('Tlist_Inc_Winwidth') + if (has('win16') || has('win95')) && !has('gui_running') + let Tlist_Inc_Winwidth = 0 + else + let Tlist_Inc_Winwidth = 1 + endif + endif + + " Vertically split taglist window width setting + if !exists('Tlist_WinWidth') + let Tlist_WinWidth = 30 + endif + + " Horizontally split taglist window height setting + if !exists('Tlist_WinHeight') + let Tlist_WinHeight = 10 + endif + + " Display tag prototypes or tag names in the taglist window + if !exists('Tlist_Display_Prototype') + let Tlist_Display_Prototype = 0 + endif + + " Display tag scopes in the taglist window + if !exists('Tlist_Display_Tag_Scope') + let Tlist_Display_Tag_Scope = 1 + endif + + " Use single left mouse click to jump to a tag. By default this is disabled. + " Only double click using the mouse will be processed. + if !exists('Tlist_Use_SingleClick') + let Tlist_Use_SingleClick = 0 + endif + + " Control whether additional help is displayed as part of the taglist or + " not. Also, controls whether empty lines are used to separate the tag + " tree. + if !exists('Tlist_Compact_Format') + let Tlist_Compact_Format = 0 + endif + + " Exit Vim if only the taglist window is currently open. By default, this is + " set to zero. + if !exists('Tlist_Exit_OnlyWindow') + let Tlist_Exit_OnlyWindow = 0 + endif + + " Automatically close the folds for the non-active files in the taglist + " window + if !exists('Tlist_File_Fold_Auto_Close') + let Tlist_File_Fold_Auto_Close = 0 + endif + + " Close the taglist window when a tag is selected + if !exists('Tlist_Close_On_Select') + let Tlist_Close_On_Select = 0 + endif + + " Automatically update the taglist window to display tags for newly + " edited files + if !exists('Tlist_Auto_Update') + let Tlist_Auto_Update = 1 + endif + + " Automatically highlight the current tag + if !exists('Tlist_Auto_Highlight_Tag') + let Tlist_Auto_Highlight_Tag = 1 + endif + + " Automatically highlight the current tag on entering a buffer + if !exists('Tlist_Highlight_Tag_On_BufEnter') + let Tlist_Highlight_Tag_On_BufEnter = 1 + endif + + " Enable fold column to display the folding for the tag tree + if !exists('Tlist_Enable_Fold_Column') + let Tlist_Enable_Fold_Column = 1 + endif + + " Display the tags for only one file in the taglist window + if !exists('Tlist_Show_One_File') + let Tlist_Show_One_File = 0 + endif + + if !exists('Tlist_Max_Submenu_Items') + let Tlist_Max_Submenu_Items = 20 + endif + + if !exists('Tlist_Max_Tag_Length') + let Tlist_Max_Tag_Length = 10 + endif + + " Do not change the name of the taglist title variable. The winmanager + " plugin relies on this name to determine the title for the taglist + " plugin. + let TagList_title = "__Tag_List__" + + " Taglist debug messages + let s:tlist_msg = '' + + " Define the taglist autocommand to automatically open the taglist window + " on Vim startup + if g:Tlist_Auto_Open + autocmd VimEnter * nested call s:Tlist_Window_Check_Auto_Open() + endif + + " Refresh the taglist + if g:Tlist_Process_File_Always + autocmd BufEnter * call s:Tlist_Refresh() + endif + + if g:Tlist_Show_Menu + autocmd GUIEnter * call s:Tlist_Menu_Init() + endif + + " When the taglist buffer is created when loading a Vim session file, + " the taglist buffer needs to be initialized. The BufFilePost event + " is used to handle this case. + autocmd BufFilePost __Tag_List__ call s:Tlist_Vim_Session_Load() + + " Define the user commands to manage the taglist window + command! -nargs=0 -bar TlistToggle call s:Tlist_Window_Toggle() + command! -nargs=0 -bar TlistOpen call s:Tlist_Window_Open() + " For backwards compatiblity define the Tlist command + command! -nargs=0 -bar Tlist TlistToggle + command! -nargs=+ -complete=file TlistAddFiles + \ call s:Tlist_Add_Files(<f-args>) + command! -nargs=+ -complete=dir TlistAddFilesRecursive + \ call s:Tlist_Add_Files_Recursive(<f-args>) + command! -nargs=0 -bar TlistClose call s:Tlist_Window_Close() + command! -nargs=0 -bar TlistUpdate call s:Tlist_Update_Current_File() + command! -nargs=0 -bar TlistHighlightTag call s:Tlist_Window_Highlight_Tag( + \ fnamemodify(bufname('%'), ':p'), line('.'), 2, 1) + " For backwards compatiblity define the TlistSync command + command! -nargs=0 -bar TlistSync TlistHighlightTag + command! -nargs=* -complete=buffer TlistShowPrototype + \ echo Tlist_Get_Tag_Prototype_By_Line(<f-args>) + command! -nargs=* -complete=buffer TlistShowTag + \ echo Tlist_Get_Tagname_By_Line(<f-args>) + command! -nargs=* -complete=file TlistSessionLoad + \ call s:Tlist_Session_Load(<q-args>) + command! -nargs=* -complete=file TlistSessionSave + \ call s:Tlist_Session_Save(<q-args>) + command! -bar TlistLock let Tlist_Auto_Update=0 + command! -bar TlistUnlock let Tlist_Auto_Update=1 + + " Commands for enabling/disabling debug and to display debug messages + command! -nargs=? -complete=file -bar TlistDebug + \ call s:Tlist_Debug_Enable(<q-args>) + command! -nargs=0 -bar TlistUndebug call s:Tlist_Debug_Disable() + command! -nargs=0 -bar TlistMessages call s:Tlist_Debug_Show() + + " Define autocommands to autoload the taglist plugin when needed. + + " Trick to get the current script ID + map <SID>xx <SID>xx + let s:tlist_sid = substitute(maparg('<SID>xx'), '<SNR>\(\d\+_\)xx$', + \ '\1', '') + unmap <SID>xx + + exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_* source ' . + \ escape(expand('<sfile>'), ' ') + exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Window_* source ' . + \ escape(expand('<sfile>'), ' ') + exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Menu_* source ' . + \ escape(expand('<sfile>'), ' ') + exe 'autocmd FuncUndefined Tlist_* source ' . + \ escape(expand('<sfile>'), ' ') + exe 'autocmd FuncUndefined TagList_* source ' . + \ escape(expand('<sfile>'), ' ') + + let loaded_taglist = 'fast_load_done' + + if g:Tlist_Show_Menu && has('gui_running') + call s:Tlist_Menu_Init() + endif + + " restore 'cpo' + let &cpo = s:cpo_save + finish +endif + +if !exists('s:tlist_sid') + " Two or more versions of taglist plugin are installed. Don't + " load this version of the plugin. + finish +endif + +unlet! s:tlist_sid + +if loaded_taglist != 'fast_load_done' + " restore 'cpo' + let &cpo = s:cpo_save + finish +endif + +" Taglist plugin functionality is available +let loaded_taglist = 'available' + +"------------------- end of user configurable options -------------------- + +" Default language specific settings for supported file types and tag types +" +" Variable name format: +" +" s:tlist_def_{vim_ftype}_settings +" +" vim_ftype - Filetype detected by Vim +" +" Value format: +" +" <ctags_ftype>;<flag>:<name>;<flag>:<name>;... +" +" ctags_ftype - File type supported by exuberant ctags +" flag - Flag supported by exuberant ctags to generate a tag type +" name - Name of the tag type used in the taglist window to display the +" tags of this type +" + +" assembly language +let s:tlist_def_asm_settings = 'asm;d:define;l:label;m:macro;t:type' + +" aspperl language +let s:tlist_def_aspperl_settings = 'asp;f:function;s:sub;v:variable' + +" aspvbs language +let s:tlist_def_aspvbs_settings = 'asp;f:function;s:sub;v:variable' + +" awk language +let s:tlist_def_awk_settings = 'awk;f:function' + +" beta language +let s:tlist_def_beta_settings = 'beta;f:fragment;s:slot;v:pattern' + +" c language +let s:tlist_def_c_settings = 'c;d:macro;g:enum;s:struct;u:union;t:typedef;' . + \ 'v:variable;f:function' + +" c++ language +let s:tlist_def_cpp_settings = 'c++;n:namespace;v:variable;d:macro;t:typedef;' . + \ 'c:class;g:enum;s:struct;u:union;f:function' + +" c# language +let s:tlist_def_cs_settings = 'c#;d:macro;t:typedef;n:namespace;c:class;' . + \ 'E:event;g:enum;s:struct;i:interface;' . + \ 'p:properties;m:method' + +" cobol language +let s:tlist_def_cobol_settings = 'cobol;d:data;f:file;g:group;p:paragraph;' . + \ 'P:program;s:section' + +" eiffel language +let s:tlist_def_eiffel_settings = 'eiffel;c:class;f:feature' + +" erlang language +let s:tlist_def_erlang_settings = 'erlang;d:macro;r:record;m:module;f:function' + +" expect (same as tcl) language +let s:tlist_def_expect_settings = 'tcl;c:class;f:method;p:procedure' + +" fortran language +let s:tlist_def_fortran_settings = 'fortran;p:program;b:block data;' . + \ 'c:common;e:entry;i:interface;k:type;l:label;m:module;' . + \ 'n:namelist;t:derived;v:variable;f:function;s:subroutine' + +" HTML language +let s:tlist_def_html_settings = 'html;a:anchor;f:javascript function' + +" java language +let s:tlist_def_java_settings = 'java;p:package;c:class;i:interface;' . + \ 'f:field;m:method' + +" javascript language +let s:tlist_def_javascript_settings = 'javascript;f:function' + +" lisp language +let s:tlist_def_lisp_settings = 'lisp;f:function' + +" lua language +let s:tlist_def_lua_settings = 'lua;f:function' + +" makefiles +let s:tlist_def_make_settings = 'make;m:macro' + +" pascal language +let s:tlist_def_pascal_settings = 'pascal;f:function;p:procedure' + +" perl language +let s:tlist_def_perl_settings = 'perl;c:constant;l:label;p:package;s:subroutine' + +" php language +let s:tlist_def_php_settings = 'php;c:class;d:constant;v:variable;f:function' + +" python language +let s:tlist_def_python_settings = 'python;c:class;m:member;f:function' + +" rexx language +let s:tlist_def_rexx_settings = 'rexx;s:subroutine' + +" ruby language +let s:tlist_def_ruby_settings = 'ruby;c:class;f:method;F:function;' . + \ 'm:singleton method' + +" scheme language +let s:tlist_def_scheme_settings = 'scheme;s:set;f:function' + +" shell language +let s:tlist_def_sh_settings = 'sh;f:function' + +" C shell language +let s:tlist_def_csh_settings = 'sh;f:function' + +" Z shell language +let s:tlist_def_zsh_settings = 'sh;f:function' + +" slang language +let s:tlist_def_slang_settings = 'slang;n:namespace;f:function' + +" sml language +let s:tlist_def_sml_settings = 'sml;e:exception;c:functor;s:signature;' . + \ 'r:structure;t:type;v:value;f:function' + +" sql language +let s:tlist_def_sql_settings = 'sql;c:cursor;F:field;P:package;r:record;' . + \ 's:subtype;t:table;T:trigger;v:variable;f:function;p:procedure' + +" tcl language +let s:tlist_def_tcl_settings = 'tcl;c:class;f:method;m:method;p:procedure' + +" vera language +let s:tlist_def_vera_settings = 'vera;c:class;d:macro;e:enumerator;' . + \ 'f:function;g:enum;m:member;p:program;' . + \ 'P:prototype;t:task;T:typedef;v:variable;' . + \ 'x:externvar' + +"verilog language +let s:tlist_def_verilog_settings = 'verilog;m:module;c:constant;P:parameter;' . + \ 'e:event;r:register;t:task;w:write;p:port;v:variable;f:function' + +" vim language +let s:tlist_def_vim_settings = 'vim;a:autocmds;v:variable;f:function' + +" yacc language +let s:tlist_def_yacc_settings = 'yacc;l:label' + +"------------------- end of language specific options -------------------- + +" Vim window size is changed by the taglist plugin or not +let s:tlist_winsize_chgd = -1 +" Taglist window is maximized or not +let s:tlist_win_maximized = 0 +" Name of files in the taglist +let s:tlist_file_names='' +" Number of files in the taglist +let s:tlist_file_count = 0 +" Number of filetypes supported by taglist +let s:tlist_ftype_count = 0 +" Is taglist part of other plugins like winmanager or cream? +let s:tlist_app_name = "none" +" Are we displaying brief help text +let s:tlist_brief_help = 1 +" List of files removed on user request +let s:tlist_removed_flist = "" +" Index of current file displayed in the taglist window +let s:tlist_cur_file_idx = -1 +" Taglist menu is empty or not +let s:tlist_menu_empty = 1 + +" An autocommand is used to refresh the taglist window when entering any +" buffer. We don't want to refresh the taglist window if we are entering the +" file window from one of the taglist functions. The 'Tlist_Skip_Refresh' +" variable is used to skip the refresh of the taglist window and is set +" and cleared appropriately. +let s:Tlist_Skip_Refresh = 0 + +" Tlist_Window_Display_Help() +function! s:Tlist_Window_Display_Help() + if s:tlist_app_name == "winmanager" + " To handle a bug in the winmanager plugin, add a space at the + " last line + call setline('$', ' ') + endif + + if s:tlist_brief_help + " Add the brief help + call append(0, '" Press <F1> to display help text') + else + " Add the extensive help + call append(0, '" <enter> : Jump to tag definition') + call append(1, '" o : Jump to tag definition in new window') + call append(2, '" p : Preview the tag definition') + call append(3, '" <space> : Display tag prototype') + call append(4, '" u : Update tag list') + call append(5, '" s : Select sort field') + call append(6, '" d : Remove file from taglist') + call append(7, '" x : Zoom-out/Zoom-in taglist window') + call append(8, '" + : Open a fold') + call append(9, '" - : Close a fold') + call append(10, '" * : Open all folds') + call append(11, '" = : Close all folds') + call append(12, '" [[ : Move to the start of previous file') + call append(13, '" ]] : Move to the start of next file') + call append(14, '" q : Close the taglist window') + call append(15, '" <F1> : Remove help text') + endif +endfunction + +" Tlist_Window_Toggle_Help_Text() +" Toggle taglist plugin help text between the full version and the brief +" version +function! s:Tlist_Window_Toggle_Help_Text() + if g:Tlist_Compact_Format + " In compact display mode, do not display help + return + endif + + " Include the empty line displayed after the help text + let brief_help_size = 1 + let full_help_size = 16 + + setlocal modifiable + + " Set report option to a huge value to prevent informational messages + " while deleting the lines + let old_report = &report + set report=99999 + + " Remove the currently highlighted tag. Otherwise, the help text + " might be highlighted by mistake + match none + + " Toggle between brief and full help text + if s:tlist_brief_help + let s:tlist_brief_help = 0 + + " Remove the previous help + exe '1,' . brief_help_size . ' delete _' + + " Adjust the start/end line numbers for the files + call s:Tlist_Window_Update_Line_Offsets(0, 1, full_help_size - brief_help_size) + else + let s:tlist_brief_help = 1 + + " Remove the previous help + exe '1,' . full_help_size . ' delete _' + + " Adjust the start/end line numbers for the files + call s:Tlist_Window_Update_Line_Offsets(0, 0, full_help_size - brief_help_size) + endif + + call s:Tlist_Window_Display_Help() + + " Restore the report option + let &report = old_report + + setlocal nomodifiable +endfunction + +" Taglist debug support +let s:tlist_debug = 0 + +" File for storing the debug messages +let s:tlist_debug_file = '' + +" Tlist_Debug_Enable +" Enable logging of taglist debug messages. +function! s:Tlist_Debug_Enable(...) + let s:tlist_debug = 1 + + " Check whether a valid file name is supplied. + if a:1 != '' + let s:tlist_debug_file = fnamemodify(a:1, ':p') + + " Empty the log file + exe 'redir! > ' . s:tlist_debug_file + redir END + + " Check whether the log file is present/created + if !filewritable(s:tlist_debug_file) + call s:Tlist_Warning_Msg('Taglist: Unable to create log file ' + \ . s:tlist_debug_file) + let s:tlist_debug_file = '' + endif + endif +endfunction + +" Tlist_Debug_Disable +" Disable logging of taglist debug messages. +function! s:Tlist_Debug_Disable(...) + let s:tlist_debug = 0 + let s:tlist_debug_file = '' +endfunction + +" Tlist_Debug_Show +" Display the taglist debug messages in a new window +function! s:Tlist_Debug_Show() + if s:tlist_msg == '' + call s:Tlist_Warning_Msg('Taglist: No debug messages') + return + endif + + " Open a new window to display the taglist debug messages + new taglist_debug.txt + " Delete all the lines (if the buffer already exists) + silent! %delete _ + " Add the messages + silent! put =s:tlist_msg + " Move the cursor to the first line + normal! gg +endfunction + +" Tlist_Log_Msg +" Log the supplied debug message along with the time +function! s:Tlist_Log_Msg(msg) + if s:tlist_debug + if s:tlist_debug_file != '' + exe 'redir >> ' . s:tlist_debug_file + silent echon strftime('%H:%M:%S') . ': ' . a:msg . "\n" + redir END + else + " Log the message into a variable + " Retain only the last 3000 characters + let len = strlen(s:tlist_msg) + if len > 3000 + let s:tlist_msg = strpart(s:tlist_msg, len - 3000) + endif + let s:tlist_msg = s:tlist_msg . strftime('%H:%M:%S') . ': ' . + \ a:msg . "\n" + endif + endif +endfunction + +" Tlist_Warning_Msg() +" Display a message using WarningMsg highlight group +function! s:Tlist_Warning_Msg(msg) + echohl WarningMsg + echomsg a:msg + echohl None +endfunction + +" Last returned file index for file name lookup. +" Used to speed up file lookup +let s:tlist_file_name_idx_cache = -1 + +" Tlist_Get_File_Index() +" Return the index of the specified filename +function! s:Tlist_Get_File_Index(fname) + if s:tlist_file_count == 0 || a:fname == '' + return -1 + endif + + " If the new filename is same as the last accessed filename, then + " return that index + if s:tlist_file_name_idx_cache != -1 && + \ s:tlist_file_name_idx_cache < s:tlist_file_count + if s:tlist_{s:tlist_file_name_idx_cache}_filename == a:fname + " Same as the last accessed file + return s:tlist_file_name_idx_cache + endif + endif + + " First, check whether the filename is present + let s_fname = a:fname . "\n" + let i = stridx(s:tlist_file_names, s_fname) + if i == -1 + let s:tlist_file_name_idx_cache = -1 + return -1 + endif + + " Second, compute the file name index + let nl_txt = substitute(strpart(s:tlist_file_names, 0, i), "[^\n]", '', 'g') + let s:tlist_file_name_idx_cache = strlen(nl_txt) + return s:tlist_file_name_idx_cache +endfunction + +" Last returned file index for line number lookup. +" Used to speed up file lookup +let s:tlist_file_lnum_idx_cache = -1 + +" Tlist_Window_Get_File_Index_By_Linenum() +" Return the index of the filename present in the specified line number +" Line number refers to the line number in the taglist window +function! s:Tlist_Window_Get_File_Index_By_Linenum(lnum) + call s:Tlist_Log_Msg('Tlist_Window_Get_File_Index_By_Linenum (' . a:lnum . ')') + + " First try to see whether the new line number is within the range + " of the last returned file + if s:tlist_file_lnum_idx_cache != -1 && + \ s:tlist_file_lnum_idx_cache < s:tlist_file_count + if a:lnum >= s:tlist_{s:tlist_file_lnum_idx_cache}_start && + \ a:lnum <= s:tlist_{s:tlist_file_lnum_idx_cache}_end + return s:tlist_file_lnum_idx_cache + endif + endif + + let fidx = -1 + + if g:Tlist_Show_One_File + " Displaying only one file in the taglist window. Check whether + " the line is within the tags displayed for that file + if s:tlist_cur_file_idx != -1 + if a:lnum >= s:tlist_{s:tlist_cur_file_idx}_start + \ && a:lnum <= s:tlist_{s:tlist_cur_file_idx}_end + let fidx = s:tlist_cur_file_idx + endif + + endif + else + " Do a binary search in the taglist + let left = 0 + let right = s:tlist_file_count - 1 + + while left < right + let mid = (left + right) / 2 + + if a:lnum >= s:tlist_{mid}_start && a:lnum <= s:tlist_{mid}_end + let s:tlist_file_lnum_idx_cache = mid + return mid + endif + + if a:lnum < s:tlist_{mid}_start + let right = mid - 1 + else + let left = mid + 1 + endif + endwhile + + if left >= 0 && left < s:tlist_file_count + \ && a:lnum >= s:tlist_{left}_start + \ && a:lnum <= s:tlist_{left}_end + let fidx = left + endif + endif + + let s:tlist_file_lnum_idx_cache = fidx + + return fidx +endfunction + +" Tlist_Exe_Cmd_No_Acmds +" Execute the specified Ex command after disabling autocommands +function! s:Tlist_Exe_Cmd_No_Acmds(cmd) + let old_eventignore = &eventignore + set eventignore=all + exe a:cmd + let &eventignore = old_eventignore +endfunction + +" Tlist_Skip_File() +" Check whether tag listing is supported for the specified file +function! s:Tlist_Skip_File(filename, ftype) + " Skip buffers with no names and buffers with filetype not set + if a:filename == '' || a:ftype == '' + return 1 + endif + + " Skip files which are not supported by exuberant ctags + " First check whether default settings for this filetype are available. + " If it is not available, then check whether user specified settings are + " available. If both are not available, then don't list the tags for this + " filetype + let var = 's:tlist_def_' . a:ftype . '_settings' + if !exists(var) + let var = 'g:tlist_' . a:ftype . '_settings' + if !exists(var) + return 1 + endif + endif + + " Skip files which are not readable or files which are not yet stored + " to the disk + if !filereadable(a:filename) + return 1 + endif + + return 0 +endfunction + +" Tlist_User_Removed_File +" Returns 1 if a file is removed by a user from the taglist +function! s:Tlist_User_Removed_File(filename) + return stridx(s:tlist_removed_flist, a:filename . "\n") != -1 +endfunction + +" Tlist_Update_Remove_List +" Update the list of user removed files from the taglist +" add == 1, add the file to the removed list +" add == 0, delete the file from the removed list +function! s:Tlist_Update_Remove_List(filename, add) + if a:add + let s:tlist_removed_flist = s:tlist_removed_flist . a:filename . "\n" + else + let idx = stridx(s:tlist_removed_flist, a:filename . "\n") + let text_before = strpart(s:tlist_removed_flist, 0, idx) + let rem_text = strpart(s:tlist_removed_flist, idx) + let next_idx = stridx(rem_text, "\n") + let text_after = strpart(rem_text, next_idx + 1) + + let s:tlist_removed_flist = text_before . text_after + endif +endfunction + +" Tlist_FileType_Init +" Initialize the ctags arguments and tag variable for the specified +" file type +function! s:Tlist_FileType_Init(ftype) + call s:Tlist_Log_Msg('Tlist_FileType_Init (' . a:ftype . ')') + " If the user didn't specify any settings, then use the default + " ctags args. Otherwise, use the settings specified by the user + let var = 'g:tlist_' . a:ftype . '_settings' + if exists(var) + " User specified ctags arguments + let settings = {var} . ';' + else + " Default ctags arguments + let var = 's:tlist_def_' . a:ftype . '_settings' + if !exists(var) + " No default settings for this file type. This filetype is + " not supported + return 0 + endif + let settings = s:tlist_def_{a:ftype}_settings . ';' + endif + + let msg = 'Taglist: Invalid ctags option setting - ' . settings + + " Format of the option that specifies the filetype and ctags arugments: + " + " <language_name>;flag1:name1;flag2:name2;flag3:name3 + " + + " Extract the file type to pass to ctags. This may be different from the + " file type detected by Vim + let pos = stridx(settings, ';') + if pos == -1 + call s:Tlist_Warning_Msg(msg) + return 0 + endif + let ctags_ftype = strpart(settings, 0, pos) + if ctags_ftype == '' + call s:Tlist_Warning_Msg(msg) + return 0 + endif + " Make sure a valid filetype is supplied. If the user didn't specify a + " valid filetype, then the ctags option settings may be treated as the + " filetype + if ctags_ftype =~ ':' + call s:Tlist_Warning_Msg(msg) + return 0 + endif + + " Remove the file type from settings + let settings = strpart(settings, pos + 1) + if settings == '' + call s:Tlist_Warning_Msg(msg) + return 0 + endif + + " Process all the specified ctags flags. The format is + " flag1:name1;flag2:name2;flag3:name3 + let ctags_flags = '' + let cnt = 0 + while settings != '' + " Extract the flag + let pos = stridx(settings, ':') + if pos == -1 + call s:Tlist_Warning_Msg(msg) + return 0 + endif + let flag = strpart(settings, 0, pos) + if flag == '' + call s:Tlist_Warning_Msg(msg) + return 0 + endif + " Remove the flag from settings + let settings = strpart(settings, pos + 1) + + " Extract the tag type name + let pos = stridx(settings, ';') + if pos == -1 + call s:Tlist_Warning_Msg(msg) + return 0 + endif + let name = strpart(settings, 0, pos) + if name == '' + call s:Tlist_Warning_Msg(msg) + return 0 + endif + let settings = strpart(settings, pos + 1) + + let cnt = cnt + 1 + + let s:tlist_{a:ftype}_{cnt}_name = flag + let s:tlist_{a:ftype}_{cnt}_fullname = name + let ctags_flags = ctags_flags . flag + endwhile + + let s:tlist_{a:ftype}_ctags_args = '--language-force=' . ctags_ftype . + \ ' --' . ctags_ftype . '-types=' . ctags_flags + let s:tlist_{a:ftype}_count = cnt + let s:tlist_{a:ftype}_ctags_flags = ctags_flags + + " Save the filetype name + let s:tlist_ftype_{s:tlist_ftype_count}_name = a:ftype + let s:tlist_ftype_count = s:tlist_ftype_count + 1 + + return 1 +endfunction + +" Tlist_Detect_Filetype +" Determine the filetype for the specified file using the filetypedetect +" autocmd. +function! s:Tlist_Detect_Filetype(fname) + " Ignore the filetype autocommands + let old_eventignore = &eventignore + set eventignore=FileType + + " Save the 'filetype', as this will be changed temporarily + let old_filetype = &filetype + + " Run the filetypedetect group of autocommands to determine + " the filetype + exe 'doautocmd filetypedetect BufRead ' . a:fname + + " Save the detected filetype + let ftype = &filetype + + " Restore the previous state + let &filetype = old_filetype + let &eventignore = old_eventignore + + return ftype +endfunction + +" Tlist_Get_Buffer_Filetype +" Get the filetype for the specified buffer +function! s:Tlist_Get_Buffer_Filetype(bnum) + let buf_ft = getbufvar(a:bnum, '&filetype') + + if bufloaded(a:bnum) + " For loaded buffers, the 'filetype' is already determined + return buf_ft + endif + + " For unloaded buffers, if the 'filetype' option is set, return it + if buf_ft != '' + return buf_ft + endif + + " Skip non-existent buffers + if !bufexists(a:bnum) + return '' + endif + + " For buffers whose filetype is not yet determined, try to determine + " the filetype + let bname = bufname(a:bnum) + + return s:Tlist_Detect_Filetype(bname) +endfunction + +" Tlist_Discard_TagInfo +" Discard the stored tag information for a file +function! s:Tlist_Discard_TagInfo(fidx) + call s:Tlist_Log_Msg('Tlist_Discard_TagInfo (' . + \ s:tlist_{a:fidx}_filename . ')') + let ftype = s:tlist_{a:fidx}_filetype + + " Discard information about the tags defined in the file + let i = 1 + while i <= s:tlist_{a:fidx}_tag_count + let fidx_i = 's:tlist_' . a:fidx . '_' . i + unlet! {fidx_i}_tag + unlet! {fidx_i}_tag_name + unlet! {fidx_i}_tag_type + unlet! {fidx_i}_ttype_idx + unlet! {fidx_i}_tag_proto + unlet! {fidx_i}_tag_searchpat + unlet! {fidx_i}_tag_linenum + let i = i + 1 + endwhile + + let s:tlist_{a:fidx}_tag_count = 0 + + " Discard information about tag type groups + let i = 1 + while i <= s:tlist_{ftype}_count + let ttype = s:tlist_{ftype}_{i}_name + if s:tlist_{a:fidx}_{ttype} != '' + let fidx_ttype = 's:tlist_' . a:fidx . '_' . ttype + let {fidx_ttype} = '' + let {fidx_ttype}_offset = 0 + let cnt = {fidx_ttype}_count + let {fidx_ttype}_count = 0 + let j = 1 + while j <= cnt + unlet! {fidx_ttype}_{j} + let j = j + 1 + endwhile + endif + let i = i + 1 + endwhile + + " Discard the stored menu command also + let s:tlist_{a:fidx}_menu_cmd = '' +endfunction + +" Tlist_Window_Update_Line_Offsets +" Update the line offsets for tags for files starting from start_idx +" and displayed in the taglist window by the specified offset +function! s:Tlist_Window_Update_Line_Offsets(start_idx, increment, offset) + let i = a:start_idx + |