From 4d4da98faef9a0ae6457bec67228d1acd99d0c29 Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Wed, 28 Dec 2005 00:00:00 +0000 Subject: [PATCH] Version 4.0b3 The following changes are made in this version: 1. Delay loading of the taglist plugin to reduce the Vim startup time. 2. Support for recursively adding multiples files to the taglist using the ':TlistAddFilesRecursive' command. 3. New ':TlistOpen' command to open and jump to the taglist window. 4. New ':TlistToggle' command to supersede the ':Tlist' command. 5. New 'Tlist_Close_On_Select' option for closing the taglist window when a file is selected. 6. New 'Tlist_Auto_Update' option to enable/disable processing of newly edited files. 7. New ':TlistLock' and ':TlistUnlock' commands to lock and unlock the taglist. 8. New 'Tlist_Highlight_Tag_On_BufEnter' option to enable/disable highlighting of the current tag on entering a buffer. 9. When the taglist buffer is created from a Vim session file, update the taglist with the files from the session file. 10. Change the background color used for highlighting file names in the taglist window. 11. When is pressed on a file name or a tag type name in the taglist window, display information about the number of tags. 12. Set the 'foldlevel' option to a high value in the taglist window. 13. When refreshing the taglist window, process all the opened buffers. 14. When moving between windows, disable and enable autocommands. 15. When a file is selected from the taglist window, use a non-plugin window to edit the file. 16. If 'Tlist_Exit_OnlyWindow' is set and when exiting Vim, make sure the '0 mark is set to the previous buffer. 17. When using the taglist plugin with the winmanager plugin and 'Tlist_Process_File_Always' is set or the taglist menu is enabled, sometimes, it is not possible to jump to other windows from the taglist window using the keyboard. Fixed this problem. 18. While opening files in a new window, use filenames instead of buffer numbers. --- doc/taglist.txt | 854 ++++++++++++++--------- plugin/taglist.vim | 1625 ++++++++++++++++++++++++++++---------------- 2 files changed, 1590 insertions(+), 889 deletions(-) diff --git a/doc/taglist.txt b/doc/taglist.txt index ae01332..98195fe 100644 --- a/doc/taglist.txt +++ b/doc/taglist.txt @@ -2,11 +2,11 @@ Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) For Vim version 6.0 and above -Last change: 2005 August 1 +Last change: 2005 December 28 1. Overview |taglist-intro| 2. Taglist on the internet |taglist-internet| -3. Requirements |taglist-requirement| +3. Requirements |taglist-requirements| 4. Installation |taglist-install| 5. Usage |taglist-using| 6. Configuration |taglist-configure| @@ -24,9 +24,10 @@ The "Tag List" plugin is a source code browser plugin for Vim. This plugin allows you to efficiently browse through source code files for different programming languages. The "Tag List" plugin provides the following features: - * Displays the tags (functions, classes, structures, variables, etc) + * Displays the tags (functions, classes, structures, variables, etc.) defined in a file in a vertically or horizontally split Vim window. - * Groups the tags by their type and displays them in a foldable tree. + * In GUI Vim, optionally displays the tags in the Tags drop-down menu and + in the popup menu. * Automatically updates the taglist window as you switch between files/buffers. As you open new files, the tags defined in the new files are added to the existing file list and the tags defined in all the @@ -34,23 +35,22 @@ programming languages. The "Tag List" plugin provides the following features: * When a tag name is selected from the taglist window, positions the cursor at the definition of the tag in the source file. * Automatically highlights the current tag name. - * In GUI Vim, optionally displays the tags in the Tags drop-down menu and - in the popup menu. + * Groups the tags by their type and displays them in a foldable tree. * Can display the prototype and scope of a tag. * Can optionally display the tag prototype instead of the tag name in the taglist window. - * The tag list can be sorted either by name or by line number. + * The tag list can be sorted either by name or by chronological order. * Supports the following language files: Assembly, ASP, Awk, Beta, C, C++, C#, Cobol, Eiffel, Erlang, Fortran, HTML, Java, Javascript, Lisp, Lua, Make, Pascal, Perl, PHP, Python, Rexx, Ruby, Scheme, Shell, Slang, SML, Sql, TCL, Verilog, Vim and Yacc. * Can be easily extended to support new languages. Support for existing languages can be modified easily. - * Provides commands to get the name and prototype of the current tag. * Provides functions to display the current tag name in the Vim status line or the window title bar. - * The list of tags displayed in the taglist window can be saved and + * The list of tags and files in the taglist can be saved and restored across Vim sessions. + * Provides commands to get the name and prototype of the current tag. * Runs in both console/terminal and GUI versions of Vim. * Works with the winmanager plugin. Using the winmanager plugin, you can use Vim plugins like the file explorer, buffer explorer and the @@ -61,18 +61,18 @@ programming languages. The "Tag List" plugin provides the following features: *taglist-internet* 2. Taglist on the internet~ -You can visit the taglist plugin home page for more information: > - +The home page of the taglist plugin is at: +> http://www.geocities.com/yegappan/taglist < -You can subscribe to the taglist mailing list to post your questions -or suggestions for improvement or bug reports. Visit the following -page for subscribing to the mailing list: > - - http://groups.yahoo.com/group/taglist/ +You can subscribe to the taglist mailing list to post your questions or +suggestions for improvement or to send bug reports. Visit the following page +for subscribing to the mailing list: +> + http://groups.yahoo.com/group/taglist < ============================================================================== - *taglist-requirement* + *taglist-requirements* 3. Requirements~ The taglist plugin will work on all the platforms where the exuberant ctags @@ -82,20 +82,21 @@ systems). The taglist plugin will work with Vim version 6.0 and above. The taglist plugin relies on the exuberant ctags utility to dynamically -generate the tag listing. You can download the exuberant ctags utility from > - +generate the tag listing. You can download the exuberant ctags utility from +> http://ctags.sourceforge.net < The exuberant ctags utility must be installed in your system to use this plugin. You should use exuberant ctags version 5.0 and above. This plugin doesn't use or create a tags file and there is no need to create a tags file to use this plugin. The taglist plugin will not work with the GNU ctags or the -Unix ctags utility. +Unix ctags utility. The exuberant ctags utility is shipped with most of the +Linux distributions. This plugin relies on the Vim "filetype" detection mechanism to determine the type of the current file. You have to turn on the Vim filetype detection by -adding the following line to your .vimrc file: > - +adding the following line to your .vimrc file: +> filetype on < The taglist plugin will not work if you run Vim in the restricted mode (using @@ -117,20 +118,20 @@ Vim without the system() function for security reasons. plugin/taglist.vim - main taglist plugin file doc/taglist.txt - documentation (help) file - Refer to the |add-plugin|, |add-global-plugin| and |runtimepath| Vim + 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/doc/vimfiles +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. Without this step, you cannot jump to the taglist help topics. 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 + '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 ":Tlist" command to open/close the taglist +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. @@ -139,126 +140,125 @@ Vim without the system() function for security reasons. 5. Usage~ Opening the taglist window~ -You can open the taglist window using the ":Tlist" command. This command will -open or close (toggle) the taglist window. You can map a key to invoke this -command. For example, the following command creates a normal mode mapping for -the key to open or close the taglist window. > +You can open the taglist window using the ":TlistOpen" or the ":TlistToggle" +commands. The ":TlistOpen" command opens the taglist window and jumps to it. +The ":TlistToggle" command opens or closes (toggle) the taglist window and the +cursor remains in the current window. - :nnoremap :Tlist +You can map a key to invoke these commands. For example, the following command +creates a normal mode mapping for the key to toggle the taglist window. +> + nnoremap :TlistToggle < -Add the above mapping to your ~/.vimrc file. You can also open the taglist -window on startup using the following command line: > - - $ vim +Tlist - -When the taglist window is opened for the first time, all the files in the -buffer list are processed and the tags for those files are displayed. If you -close the taglist window, the tags information displayed in the taglist window -will not be lost. The next time you open the taglist window in the same Vim -session, the stored tags information will be displayed. +Add the above mapping to your ~/.vimrc file. +To automatically open the taglist window on Vim startup, set the +'Tlist_Auto_Open' variable to 1. You can also open the taglist window on +startup using the following command line: +> + $ vim +TlistOpen +< Closing the taglist window~ You can close the taglist window from the taglist window by pressing 'q' or -using the Vim ":q" command. You can also use any of the Vim window commands -to close the taglist window. Invoking the ":Tlist" command when the taglist -window is opened, will close the taglist window. You can also close the -taglist window by invoking the ":TlistClose" command. +using the Vim ":q" command. You can also use any of the Vim window commands to +close the taglist window. Invoking the ":TlistToggle" command when the taglist +window is opened, closes the taglist window. You can also use the +":TlistClose" command to close the taglist window. -Taglist window contents~ -As you switch between source files, the taglist window will be automatically -updated with the tags defined in the current source file. The tag names will -grouped by their type (variable, function, class, etc). For tags with scope -information (like class members, structures inside structures, etc), the scope -information will be displayed in square brackets "[]" after the tagname. - -Opening and closing the tag and file tree~ -The tag names will be displayed as a foldable tree using the Vim folding -support. You can collapse the tree using the '-' key or using the Vim zc -fold command. You can open the tree using the '+' key or using the Vim zo -fold command. You can open all the folds using the '*' key or using the Vim -zR fold command. You can also use the mouse to open/close the folds. You -can close all the folds using the '=' key. +To automatically close the taglist window when a tag or file is selected, you +can set the 'Tlist_Close_On_Select' variable to 1. To exit Vim when only the +taglist window is present, set the 'Tlist_Exit_OnlyWindow' variable to 1. Jumping to a tag or a file~ -You can select a tag either by pressing the key or by double clicking -the tag name using the mouse. You can jump to a tag using a single mouse click -by setting the 'Tlist_Use_SingleClick' variable. You can press the 'o' key to -jump to the tag in a new window. You can press the 'p' key to jump to the tag -but still keep the cursor in the taglist window itself. +You can select a tag in the taglist window either by pressing the key +or by double clicking the tag name using the mouse. To jump to a tag on a +single mouse click set the 'Tlist_Use_SingleClick' variable to 1. To jump to +the tag in a new window, press the 'o' key. You can press the 'p' key to jump +to the tag but still keep the cursor in the taglist window itself (preview). -You can open a file by pressing key or by double clicking the file +You can open a file by pressing the key or by double clicking the file name using the mouse. In the taglist window, you can use the [[ or key to jump to the beginning of the previous file. You can use the ]] or key to jump to the beginning of the next file. -Syncing the taglist window~ -The taglist plugin will automatically highlight the name of the current tag. -The tag name will be highlighted after |updatetime| milliseconds. The default -value for this Vim option is 4 seconds. To avoid unexpected problems, you -should not set the |updatetime| option to very low values. You can also use -the ":TlistSync" command to force the highlighting of the current tag. +Highlighting the current tag~ +The taglist plugin automatically highlights the name of the current tag in the +taglist window. The Vim |CursorHold| autocmd event is used for this. If the +current tag name is not visible in the taglist window, then the taglist window +contents are scrolled to make that tag name visible. You can also use the +":TlistHighlightTag" command to force the highlighting of the current tag. -Displaying the tag prototype~ -If you place the cursor on a tag name in the taglist window, then the tag -prototype will be displayed at the Vim status line after |updatetime| -milliseconds. The default value for the |updatetime| Vim option is 4 -seconds. You can also press the space bar to display the prototype of the -tag under the cursor in the taglist window. +The tag name is highlighted if no activity is performed for |'updatetime'| +milliseconds. The default value for this Vim option is 4 seconds. To avoid +unexpected problems, you should not set the |'updatetime'| option to a very +low value. -You can use the ":TlistShowPrototype" command to display the prototype of the -tag at or below the specified line number. For example, > +To disable the automatic highlighting of the current tag name in the taglist +window, set the 'Tlist_Auto_Highlight_Tag' variable to zero. - :TlistShowPrototype myfile.c 50 -< -If the file name and line number are not supplied, then this command will -display the prototype of the current tag. +When entering a Vim buffer/window, the taglist plugin automatically highlights +the current tag in that buffer/window. If you like to disable the automatic +highlighting of the current tag when entering a buffer, set the +'Tlist_Highlight_Tag_On_BufEnter' variable to zero. -You can use the ":TlistShowTag" command to display the name of the tag at or -below the specified line number. For example, +Adding files to the taglist~ +When the taglist window is opened, all the files in the Vim buffer list are +processed and the supported files are added to the taglist. When you edit a +file in Vim, the taglist plugin automatically processes this file and adds it +to the taglist. If you close the taglist window, the tag information in the +taglist is retained. + +To process files even when the taglist window is not open, set the +'Tlist_Process_File_Always' variable to 1. + +You can manually add multiple files to the taglist without opening them using +the ":TlistAddFiles" and the ":TlistAddFilesRecursive" commands. + +For example, to add all the C files in the /my/project/dir directory to the +taglist, you can use the following command: > - :TlistShowTag myfile.java 100 + :TlistAddFiles /my/project/dir/*.c < -If the file name and line number are not supplied, then this command will -display the name of the current tag. +Note that when adding several files with a large number of tags or a large +number of files, it will take several seconds to several minutes for the +taglist plugin to process all the files. You should not interrupt the taglist +plugin by pressing . -The above two commands will work even when the taglist window is closed. To -use this command on newly opened files without the taglist window and the -taglist menu, you should set the Tlist_Process_File_Always variable to 1. +You can recursively add multiple files from a directory tree using the +":TlistAddFilesRecursive" command: +> + :TlistAddFilesRecursive /my/project/dir *.c +< +This command takes two arguments. The first argument specifies the directory +from which to recursively add the files. The second optional argument +specifies the wildcard matching pattern for selecting the files to add. The +default pattern is * and all the files are added. -Sorting the tags for a file~ -The tags displayed in the taglist window can be sorted either by name of by -their chronological order. The default sorting order is by the order in which -the tags appear in the file. You can change the default sort order by setting -the Tlist_Sort_Type variable. You can sort the tags by their name by pressing -the "s" key in the taglist window. You can again sort the tags by their -chronological order using the "s" key. Each file in the taglist window can be -sorted using different order. - -Removing the tags listed for a file from the taglist window~ -You can remove the tags displayed for a file, by pressing the 'd' key when the +Removing files from the taglist~ +You can remove a file from the taglist window, by pressing the 'd' key when the cursor is on one of the tags listed for the file in the taglist window. The -removed file is no longer displayed in the taglist window. To again display -the tags for the file, open the file in a Vim window and then use the -:TlistUpdate command. +removed file will no longer be displayed in the taglist window in the current +Vim session. To again display the tags for the file, open the file in a Vim +window and then use the ":TlistUpdate" command or use ":TlistAddFiles" command +to add the file to the taglist. -Zooming in and out of the taglist window~ -You can press the 'x' key in the taglist window to maximize the taglist -window width/height. The window will be maximized to the maximum possible -width/height without closing the other existing windows. You can again press -'x' to restore the taglist window to the default width/height. +When a buffer is removed from the Vim buffer list using the ":bdelete" or +the ":bwipe" command, the taglist is updated to remove the stored information +for this buffer. Updating the tags displayed for a file~ The taglist plugin keeps track of the modification time of a file. When the -modification time changes (the file is modified), the taglist plugin will -automatically update the tags listed for that file. The modification time is -checked when you enter a window containing the file or when you load the file. +modification time changes (the file is modified), the taglist plugin +automatically updates the tags listed for that file. The modification time of +a file is checked when you enter a window containing that file or when you +load that file. You can also update or refresh the tags displayed for a file by pressing the "u" key in the taglist window. If an existing file is modified, after the file -is saved, the taglist plugin will automatically update the tags displayed for -the file. +is saved, the taglist plugin automatically updates the tags displayed for the +file. You can also use the ":TlistUpdate" command to update the tags for the current buffer after you made some changes to it. You should save the modified buffer @@ -267,60 +267,125 @@ include the new tags created in the buffer. If you have deleted the tags displayed for a file in the taglist window using the 'd' key, you can again display the tags for that file using the -':TlistUpdate' command. +":TlistUpdate" command. -Adding multiples files to the taglist window~ -You can add the tags defined in a file(s) without opening it using the -":TlistAddFiles" command. For example, to add the tags defined in all -the C files in a directory, you can use the following command: +Controlling the taglist updates~ +To disable the automatic processing of new files or modified files, you can +set the 'Tlist_Auto_Update' variable to zero. When this variable is set to +zero, the taglist is updated only when you use the ":TlistUpdate" command or +the ":TlistAddFiles" or the ":TlistAddFilesRecursive" commands. You can use +this option to control which files are added to the taglist. - :TlistAddFiles my/project/dir/*.c +You can use the ":TlistLock" command to lock the taglist contents. After this +command is executed, new files are not automatically added to the taglist. +When the taglist is locked, you can use the ":TlistUpdate" command to add the +current file or the ":TlistAddFiles" or ":TlistAddFilesRecursive" commands to +add new files to the taglist. To unlock the taglist, use the ":TlistUnlock" +command. -Note that if you try to add several files with a large number of tags or a -large number of files, then it will take several seconds to minutes for the -taglist plugin to process all the files. +Displaying the tag prototype~ +To display the prototype of the tag under the cursor in the taglist window, +press the space bar. If you place the cursor on a tag name in the taglist +window, then the tag prototype is displayed at the Vim status line after +|'updatetime'| milliseconds. The default value for the |'updatetime'| Vim +option is 4 seconds. + +You can get the name and prototype of a tag without opening the taglist window +and the taglist menu using the ":TlistShowTag" and the ":TlistShowPrototype" +commands. To use these commands without the taglist window, set the +'Tlist_Process_File_Always' variable to 1. + +You can use the ":TlistShowTag" command to display the name of the tag at or +before the specified line number in the specified file. If the file name and +line number are not supplied, then this command will display the name of the +current tag. For example, +> + :TlistShowTag + :TlistShowTag myfile.java 100 +< +You can use the ":TlistShowPrototype" command to display the prototype of the +tag at or before the specified line number in the specified file. If the file +name and the line number are not supplied, then this command will display the +prototype of the current tag. For example, +> + :TlistShowPrototype + :TlistShowPrototype myfile.c 50 +< +Taglist window contents~ +The taglist window displays the tags for all the files in the Vim buffer list +and all the manually added files. To display the tags for only the current +active buffer, set the 'Tlist_Show_One_File' variable to 1. + +The tag names are grouped by their type (variable, function, class, etc.). For +tags with scope information (like class members, structures inside structures, +etc.), the scope information is displayed in square brackets "[]" after the tag +name. -Modifying the contents of the taglist buffer/window~ The contents of the taglist buffer/window are managed by the taglist plugin. -The Vim 'modifiable' option is turned off for the taglist buffer. You should -not manually edit the taglist buffer, by setting the 'modifiable' flag. If you -manually edit the taglist buffer contents, then the taglist plugin will be out -of sync with the taglist buffer contents and the plugin will no longer work -correctly. To redisplay the taglist buffer contents again, you can close the +The Vim |'modifiable'| option is turned off for the taglist buffer. You should +not manually edit the taglist buffer, by setting the |'modifiable'| flag. If +you manually edit the taglist buffer contents, then the taglist plugin will be +out of sync with the taglist buffer contents and the plugin will no longer +work correctly. To redisplay the taglist buffer contents again, close the taglist window and reopen it. +Opening and closing the tag and file tree~ +In the taglist window, the tag names are displayed as a foldable tree using +the Vim folding support. You can collapse the tree using the '-' key or using +the Vim |zc| fold command. You can open the tree using the '+' key or using +the Vim |zo| fold command. You can open all the folds using the '*' key or +using the Vim |zR| fold command. You can also use the mouse to open/close the +folds. You can close all the folds using the '=' key. You should not manually +create or delete the folds in the taglist window. + +To automatically close the fold for the inactive files/buffers and open only +the fold for the current buffer in the taglist window, set the +'Tlist_File_Fold_Auto_Close' variable to 1. + +Sorting the tags for a file~ +The tags displayed in the taglist window can be sorted either by their name or +by their chronological order. The default sorting method is by the order in +which the tags appear in a file. You can change the default sort method by +setting the 'Tlist_Sort_Type' variable to either "name" or "order". You can +sort the tags by their name by pressing the "s" key in the taglist window. You +can again sort the tags by their chronological order using the "s" key. Each +file in the taglist window can be sorted using different order. + +Zooming in and out of the taglist window~ +You can press the 'x' key in the taglist window to maximize the taglist +window width/height. The window will be maximized to the maximum possible +width/height without closing the other existing windows. You can again press +'x' to restore the taglist window to the default width/height. + *taglist-session* Taglist Session~ -A taglist session refers to the group of files and their tags displayed in the -taglist window in a Vim session. +A taglist session refers to the group of files and their tags stored in the +taglist in a Vim session. You can save and restore a taglist session (and all the displayed tags) using -the :TlistSessionSave and :TlistSessionLoad commands. - -To save all the tags displayed in the taglist window to a file, use the -:TlistSessionSave command and specify the filename: > +the ":TlistSessionSave" and ":TlistSessionLoad" commands. +To save the information about the tags and files in the taglist to a file, use +the ":TlistSessionSave" command and specify the filename: +> :TlistSessionSave < -To load the saved taglist session, use the TlistSessionLoad command: > +To load a saved taglist session, use the ":TlistSessionLoad" command: > :TlistSessionLoad < -Information about the tags displayed for the files in the taglist window will -be stored in the taglist session file. This will be used to restore the -taglist window state later. When you load a taglist session file, the tags -stored in the file will be added to the tags already displayed in the taglist -window. +When you load a taglist session file, the tags stored in the file will be +added to the tags already stored in the taglist. The taglist session feature can be used to save the tags for large files or a group of frequently used files (like a project). By using the taglist session file, you can minimize the amount to time it takes to load/refresh the taglist -window for multiple files. +for multiple files. You can create more than one taglist session file for multiple groups of files. -Displaying tag name in the Vim status line or the window title bar~ +Displaying the tag name in the Vim status line or the window title bar~ You can use the Tlist_Get_Tagname_By_Line() function provided by the taglist plugin to display the current tag name in the Vim status line or the window title bar. Similarly, you can use the Tlist_Get_Tag_Prototype_By_Line() @@ -341,7 +406,7 @@ Note that the current tag name can be displayed only after the file is processed by the taglist plugin. For this, you have to either set the 'Tlist_Process_File_Always' variable to 1 or open the taglist window or use the taglist menu. For more information about configuring the Vim status line, -refer to the documentation for the |'statusline'| option. +refer to the documentation for the Vim |'statusline'| option. Changing the taglist window highlighting~ The following Vim highlight groups are defined and used to highlight the @@ -350,22 +415,43 @@ various entities in the taglist window: TagListTagName - Used for tag names TagListTagScope - Used for tag scope TagListTitle - Used for tag titles - TagListComment - Used for comments in the taglist window + TagListComment - Used for comments TagListFileName - Used for filenames By default, these highlight groups are linked to the standard Vim highlight -groups. If you want to change these highlight groups, you can prefix 'My' -to the above highlight group names and define them in your .vimrc file. The -taglist plugin will use the defined highlight groups instead of the default -groups. For example, to change the highlighting used for tag names, you can -use: > - - :highlight MyTagListTagName guifg=cyan +groups. If you want to change the colors used for these highlight groups, you +can define them in your .vimrc or .gvimrc files. For example, to change the +highlighting used for tag names, you can use: +> + :highlight TagListTagName guifg=DarkGreen ctermfg=DarkGreen < -Getting help~ -You can press the "?" key in the taglist window to display the help -information about using the taglist window. If you again press the '?' key, -the help information will be removed from the taglist window. +Controlling the taglist window~ +To use a horizontally split taglist window, instead of a vertically split +window, set the 'Tlist_Use_Horiz_Window' variable to 1. + +To use a vertically split taglist window on the rightmost side of the Vim +window, set the 'Tlist_Use_Right_Window' variable to 1. + +You can specify the width of the vertically split taglist window, by setting +the 'Tlist_WinWidth' variable. You can specify the height of the horizontally +split taglist window, by setting the 'Tlist_WinHeight' variable. + +When opening a vertically split taglist window, the Vim window width is +increased to accommodate the new taglist window. When the taglist window is +closed, the Vim window is reduced. To disable this, set the +'Tlist_Inc_Winwidth' variable to zero. + +To reduce the number of empty lines in the taglist window, set the +'Tlist_Compact_Format' variable to 1. + +To not display the Vim fold column in the taglist window, set the +'Tlist_Enable_Fold_Column' variable to zero. + +To display the tag prototypes instead of the tag names in the taglist window, +set the 'Tlist_Display_Prototype' variable to 1. + +To not display the scope of the tags next to the tag names, set the +'Tlist_Display_Tag_Scope' variable to zero. *taglist-keys* Taglist window key list~ @@ -381,6 +467,9 @@ in the taglist window. p Display the tag definition in the file window and keep the cursor in the taglist window itself. Display the prototype of the tag under the cursor. + For file names, display the full path to the file, + file type and the number of tags. For tag types, display the + tag type and the number of tags. u Update the tags listed in the taglist window s Change the sort order of the tags (by name or by order) d Remove the tags for the file under the cursor @@ -413,16 +502,16 @@ When you switch between files/buffers, the taglist menu is automatically updated to display the tags defined in the current file/buffer. The tags are grouped by their type (variables, functions, classes, methods, -etc) and displayed as a separate sub-menu for each type. +etc.) and displayed as a separate sub-menu for each type. If the number of items in a tag type submenu exceeds the value specified by -the Tlist_Max_Submenu_Items variable, then the submenu will be split into -multiple submenus. The default setting for Tlist_Max_Submenu_Items is 25. The -first and last tag names in the submenu are used to form the submenu name. The -menu items are prefixed by alpha-numeric characters for easy selection by +the 'Tlist_Max_Submenu_Items' variable, then the submenu will be split into +multiple submenus. The default setting for 'Tlist_Max_Submenu_Items' is 25. +The first and last tag names in the submenu are used to form the submenu name. +The menu items are prefixed by alpha-numeric characters for easy selection by keyboard. -If the popup menu support is enabled (the 'mousemodel' option contains +If the popup menu support is enabled (the |'mousemodel'| option contains "popup"), then the tags menu is added to the popup menu. You can access the popup menu by right clicking on the GUI window. @@ -443,13 +532,25 @@ the following setting: > let winManagerWindowLayout = 'FileExplorer|TagList' < +Getting help~ +If you have installed the taglist help file (this file), then you can use the +Vim ":help taglist-" command to get help on the various taglist +topics. + +You can press the "?" key in the taglist window to display the help +information about using the taglist window. If you again press the '?' key, +the help information is removed from the taglist window. + *taglist-debug* Debugging the taglist plugin~ You can use the ":TlistDebug" command to enable logging of the debug messages from the taglist plugin. To display the logged debug messages, you can use the ":TlistMessages" command. To disable the logging of the debug messages, use -the ":TlistUndebug" command. The debug messages are stored in a script-local -variable by the taglist plugin. To minimize memory usage, only the last 3000 +the ":TlistUndebug" command. + +You can specify a file name to the ":TlistDebug" command to log the debug +messages to a file. Otherwise, the debug messages are stored in a script-local +variable. In the later case, to minimize memory usage, only the last 3000 characters from the debug messages are stored. ============================================================================== @@ -460,69 +561,98 @@ A number of Vim variables control the behavior of the taglist plugin. These variables are initialized to a default value. By changing these variables you can change the behavior of the taglist plugin. You need to change these settings only if you want to change the behavior of the taglist plugin. You -should use the |let| command in your .vimrc file to change the setting of any +should use the |:let| command in your .vimrc file to change the setting of any of these variables. The configurable taglist variables are listed below. For a detailed description of these variables refer to the text below this table. -|'Tlist_Auto_Highlight_Tag'| Highlight the current tag in the taglist. +|'Tlist_Auto_Highlight_Tag'| Automatically highlight the current tag in the + taglist. |'Tlist_Auto_Open'| Open the taglist window when Vim starts. +|'Tlist_Auto_Update'| Automatically update the taglist to include + newly edited files. +|'Tlist_Close_On_Select'| Close the taglist window when a file or tag is + selected. |'Tlist_Compact_Format'| Remove extra information and blank lines from the taglist window. |'Tlist_Ctags_Cmd'| Specifies the path to the ctags utility. -|'Tlist_Display_Prototype'| Show prototypes, not just tags. +|'Tlist_Display_Prototype'| Show prototypes and not tags in the taglist + window. |'Tlist_Display_Tag_Scope'| Show tag scope next to the tag name. -|'Tlist_Enable_Fold_Column'| Show the fold indicator column. -|'Tlist_Exit_OnlyWindow'| Close VIM if the taglist is the only window. -|'Tlist_File_Fold_Auto_Close'| Close tag folds for all buffers not shown. -|'Tlist_Inc_Winwidth'| Expand the current window to accommodate the - taglist window. +|'Tlist_Enable_Fold_Column'| Show the fold indicator column in the taglist + window. +|'Tlist_Exit_OnlyWindow'| Close Vim if the taglist is the only window. +|'Tlist_File_Fold_Auto_Close'| Close tag folds for inactive buffers. +|'Tlist_Highlight_Tag_On_BufEnter'| + On entering a buffer, automatically highlight + the current tag. +|'Tlist_Inc_Winwidth'| Increase the Vim window width to accommodate + the taglist window. |'Tlist_Max_Submenu_Items'| Maximum number of items in a tags sub-menu. |'Tlist_Max_Tag_Length'| Maximum tag length used in a tag menu entry. -|'Tlist_Process_File_Always'| Process tags for files when the taglist window - is closed. +|'Tlist_Process_File_Always'| Process files even when the taglist window is + closed. |'Tlist_Show_Menu'| Display the tags menu. |'Tlist_Show_One_File'| Show tags for the current buffer only. |'Tlist_Sort_Type'| Sort method used for arranging the tags. |'Tlist_Use_Horiz_Window'| Use a horizontally split window for the taglist window. -|'Tlist_Use_Right_Window'| Put the taglist window on the right side. +|'Tlist_Use_Right_Window'| Place the taglist window on the right side. |'Tlist_Use_SingleClick'| Single click on a tag jumps to it. |'Tlist_WinHeight'| Horizontally split taglist window height. |'Tlist_WinWidth'| Vertically split taglist window width. *'Tlist_Auto_Highlight_Tag'* Tlist_Auto_Highlight_Tag~ -By default, the taglist plugin will highlight the current tag in the taglist -window. If you want to disable the highlighting of the current tag, then you -can set the Tlist_Auto_Highlight_Tag variable to zero. Note that even though -the current tag highlighting is disabled, the tags for a new file will still -be added to the taglist window. +The taglist plugin will automatically highlight the current tag in the taglist +window. If you want to disable this, then you can set the +Tlist_Auto_Highlight_Tag variable to zero. Note that even though the current +tag highlighting is disabled, the tags for a new file will still be added to +the taglist window. > let Tlist_Auto_Highlight_Tag = 0 < -You can still use the ':TlistSync' command to highlight the current tag. +You can still use the ":TlistHighlightTag" command to highlight the current +tag. *'Tlist_Auto_Open'* Tlist_Auto_Open~ To automatically open the taglist window, when you start Vim, you can set the -'Tlist_Auto_Open' variable to 1. By default, this variable is set to 0 and the -taglist window will not be opened automatically on Vim startup. > - +'Tlist_Auto_Open' variable to 1. By default, this variable is set to zero and +the taglist window will not be opened automatically on Vim startup. +> let Tlist_Auto_Open = 1 < The taglist window is opened only when a supported type of file is opened on Vim startup. For example, if you open text files, then the taglist window will not be opened. + *'Tlist_Auto_Update'* +Tlist_Auto_Update~ +When a new file is edited, the tags defined in the file are automatically +processed and added to the taglist. To stop adding new files to the taglist, +set the 'Tlist_Auto_Update' variable to zero. By default, this variable is set +to 1. +> + let Tlist_Auto_Update = 0 +< + *'Tlist_Close_On_Select'* +Tlist_Close_On_Select~ +If you want to close the taglist window when a file or tag is selected, then +set the 'Tlist_Close_On_Select' variable to 1. By default, this variable is +set zero and when you select a tag or file from the taglist window, the window +will not be closed. +> + let Tlist_Close_On_Select = 1 +< *'Tlist_Compact_Format'* Tlist_Compact_Format~ By default, empty lines are used to separate different tag types displayed for a file and the tags displayed for different files in the taglist window. If you want to display as many tags as possible in the taglist window, you can -set the Tlist_Compact_Format variable to one to get a compact display. > - +set the 'Tlist_Compact_Format' variable to 1 to get a compact display. +> let Tlist_Compact_Format = 1 < *'Tlist_Ctags_Cmd'* @@ -532,7 +662,7 @@ ctags utility. If exuberant ctags is present in any one of the directories in the PATH environment variable, then there is no need to set this variable. The exuberant ctags tool can be installed under different names. When the -taglist plugin starts up, if the Tlist_Ctags_Cmd variable is not set, it +taglist plugin starts up, if the 'Tlist_Ctags_Cmd' variable is not set, it checks for the names exuberant-ctags, ctags, ctags.exe and tags in the PATH environment variable. If any one of the named executable is found, then the Tlist_Ctags_Cmd variable is set to that name. @@ -552,36 +682,36 @@ loaded. Tlist_Display_Prototype~ By default, only the tag name will be displayed in the taglist window. If you like to see tag prototypes instead of names, set the 'Tlist_Display_Prototype' -variable to 1. By default, this variable is set to 0 and only tag names will -be displayed. > - +variable to 1. By default, this variable is set to zero and only tag names +will be displayed. +> let Tlist_Display_Prototype = 1 < *'Tlist_Display_Tag_Scope'* Tlist_Display_Tag_Scope~ By default, the scope of a tag (like a C++ class) will be displayed in square brackets next to the tag name. If you don't want the tag scopes -to be displayed, then set the 'Tlist_Display_Tag_Scope' to 0. By default, -this variable is set to 1 and the tag scopes will be displayed. > - +to be displayed, then set the 'Tlist_Display_Tag_Scope' to zero. By default, +this variable is set to 1 and the tag scopes will be displayed. +> let Tlist_Display_Tag_Scope = 0 < *'Tlist_Enable_Fold_Column'* Tlist_Enable_Fold_Column~ By default, the Vim fold column is enabled and displayed in the taglist window. If you wish to disable this (for example, when you are working with a -narrow Vim window or terminal), you can set the Tlist_Enable_Fold_Column -variable to 0. +narrow Vim window or terminal), you can set the 'Tlist_Enable_Fold_Column' +variable to zero. > let Tlist_Enable_Fold_Column = 1 < *'Tlist_Exit_OnlyWindow'* Tlist_Exit_OnlyWindow~ If you want to exit Vim if only the taglist window is currently opened, then -set the Tlist_Exit_OnlyWindow variable to one. By default, this variable is +set the 'Tlist_Exit_OnlyWindow' variable to 1. By default, this variable is set to zero and the Vim instance will not be closed if only the taglist window -is present. > - +is present. +> let Tlist_Exit_OnlyWindow = 1 < *'Tlist_File_Fold_Auto_Close'* @@ -595,32 +725,44 @@ in the taglist window will be collapsed/folded. When a buffer is loaded in a Vim window, the corresponding tags tree will be opened. > let Tlist_File_Fold_Auto_Close = 1 +< + *'Tlist_Highlight_Tag_On_BufEnter'* +Tlist_Highlight_Tag_On_BufEnter~ +When you enter a Vim buffer/window, the current tag in that buffer/window is +automatically highlighted in the taglist window. If the current tag name is +not visible in the taglist window, then the taglist window contents are +scrolled to make that tag name visible. If you like to disable the automatic +highlighting of the current tag when entering a buffer, you can set the +'Tlist_Highlight_Tag_On_BufEnter' variable to zero. The default setting for +this variable is 1. +> + let Tlist_Highlight_Tag_On_BufEnter = 0 < *'Tlist_Inc_Winwidth'* Tlist_Inc_Winwidth~ By default, when the width of the window is less than 100 and a new taglist window is opened vertically, then the window width will be increased by the -value set in the Tlist_WinWidth variable to accommodate the new window. The +value set in the 'Tlist_WinWidth' variable to accommodate the new window. The value of this variable is used only if you are using a vertically split taglist window. If your terminal doesn't support changing the window width from Vim (older version of xterm running in a Unix system) or if you see any weird problems in the screen due to the change in the window width or if you prefer not to -adjust the window width then set the 'Tlist_Inc_Winwidth' variable to 0. +adjust the window width then set the 'Tlist_Inc_Winwidth' variable to zero. CAUTION: If you are using the MS-Windows version of Vim in a MS-DOS command -window then you must set this variable to 0, otherwise the system may hang due -to a Vim limitation (explained in :help win32-problems) > - +window then you must set this variable to zero, otherwise the system may hang +due to a Vim limitation (explained in :help win32-problems) +> let Tlist_Inc_Winwidth = 0 < *'Tlist_Max_Submenu_Items'* Tlist_Max_Submenu_Items~ If a file contains too many tags of a particular type (function, variable, -class, etc.), greater than that specified by the Tlist_Max_Submenu_Items +class, etc.), greater than that specified by the 'Tlist_Max_Submenu_Items' variable, then the menu for that tag type will be split into multiple -sub-menus. The default setting for the Tlist_Max_Submenu_Items variable is 25. -This can be changed by setting the Tlist_Max_Submenu_Items variable: +sub-menus. The default setting for the 'Tlist_Max_Submenu_Items' variable is +25. This can be changed by setting the 'Tlist_Max_Submenu_Items' variable: > let Tlist_Max_Submenu_Items = 20 < @@ -629,9 +771,10 @@ tag entries in that submenu. *'Tlist_Max_Tag_Length'* Tlist_Max_Tag_Length~ -Only the first Tlist_Max_Tag_Length characters from the tag names will be used -to form the tag type submenu name. Change the Tlist_Max_Tag_Length setting if -you want to include more or less characters: +Only the first 'Tlist_Max_Tag_Length' characters from the tag names will be +used to form the tag type submenu name. The default value for this variable is +10. Change the 'Tlist_Max_Tag_Length' setting if you want to include more or +less characters: > let Tlist_Max_Tag_Length = 10 < @@ -642,20 +785,20 @@ the newly opened files only when the taglist window is opened or when the taglist menu is enabled. When the taglist window is closed, the taglist plugin will stop processing the tags for newly opened files. -You can set the Tlist_Process_File_Always variable to 1 to generate the list +You can set the 'Tlist_Process_File_Always' variable to 1 to generate the list of tags for new files even when the taglist window is closed and the taglist menu is disabled. > let Tlist_Process_File_Always = 1 < -You should set this variable to 1, if you want to use the :TlistShowTag and -:TlistShowPrototype commands without the taglist window and the taglist menu. +To use the ":TlistShowTag" and the ":TlistShowPrototype" commands without the +taglist window and the taglist menu, you should set this variable to 1. *'Tlist_Show_Menu'* Tlist_Show_Menu~ When using GUI Vim, you can display the tags defined in the current file in a menu named "Tags". By default, this feature is turned off. To turn on this -feature, set the Tlist_Show_Menu variable to one: +feature, set the 'Tlist_Show_Menu' variable to 1: > let Tlist_Show_Menu = 1 < @@ -678,8 +821,8 @@ by the order of their appearance in the file (chronological order). By default, the tag names will be listed by the order in which they are defined in the file. You can change the sort type (from name to order or from order to name) by pressing the "s" key in the taglist window. You can also change the -default sort order by setting 'Tlist_Sort_Type' to "name" or "order": > - +default sort order by setting 'Tlist_Sort_Type' to "name" or "order": +> let Tlist_Sort_Type = "name" < *'Tlist_Use_Horiz_Window'* @@ -690,60 +833,60 @@ variable to 1. If you are running MS-Windows version of Vim in a MS-DOS command window, then you should use a horizontally split window instead of a vertically split window. Also, if you are using an older version of xterm in a Unix system that doesn't support changing the xterm window width, you should -use a horizontally split window. > - +use a horizontally split window. +> let Tlist_Use_Horiz_Window = 1 < *'Tlist_Use_Right_Window'* Tlist_Use_Right_Window~ By default, the vertically split taglist window will appear on the left hand side. If you prefer to open the window on the right hand side, you can set the -'Tlist_Use_Right_Window' variable to one: > - +'Tlist_Use_Right_Window' variable to 1: +> let Tlist_Use_Right_Window = 1 < *'Tlist_Use_SingleClick'* Tlist_Use_SingleClick~ By default, when you double click on the tag name using the left mouse button, the cursor will be positioned at the definition of the tag. You -can set the Tlist_Use_SingleClick variable to 1 to jump to a tag when +can set the 'Tlist_Use_SingleClick' variable to 1 to jump to a tag when you single click on the tag name using the mouse. By default this variable -is set to zero. > - +is set to zero. +> let Tlist_Use_SingleClick = 1 < -Due to a bug in Vim, if you set Tlist_Use_SingleClick to one and try to resize -the taglist window using the mouse, then Vim will crash. The fix for this bug -will be available in Vim 6.3 and above. In the meantime, instead of resizing -the taglist window using the mouse, you can use normal Vim window resizing -commands to resize the taglist window. +Due to a bug in Vim, if you set 'Tlist_Use_SingleClick' to 1 and try to resize +the taglist window using the mouse, then Vim will crash. This problem is fixed +in Vim 6.3 and above. In the meantime, instead of resizing the taglist window +using the mouse, you can use normal Vim window resizing commands to resize the +taglist window. *'Tlist_WinHeight'* Tlist_WinHeight~ The default height of the horizontally split taglist window is 10. This can be -changed by modifying the 'Tlist_WinHeight' variable: > - +changed by modifying the 'Tlist_WinHeight' variable: +> let Tlist_WinHeight = 20 < -The 'winfixheight' option is set for the the taglist window, to maintain the +The |'winfixheight'| option is set for the taglist window, to maintain the height of the taglist window, when new Vim windows are opened and existing windows are closed. *'Tlist_WinWidth'* Tlist_WinWidth~ The default width of the vertically split taglist window is 30. This can be -changed by modifying the 'Tlist_WinWidth' variable: > - +changed by modifying the 'Tlist_WinWidth' variable: +> let Tlist_WinWidth = 20 < -Note that the value of the |winwidth| option setting determines the minimum +Note that the value of the |'winwidth'| option setting determines the minimum width of the current window. If you set the 'Tlist_WinWidth' variable to a -value less than that of the |winwidth| option setting, then Vim will use the -value of the |winwidth| option. +value less than that of the |'winwidth'| option setting, then Vim will use the +value of the |'winwidth'| option. When new Vim windows are opened and existing windows are closed, the taglist plugin will try to maintain the width of the taglist window to the size -specified by the Tlist_WinWidth variable. +specified by the 'Tlist_WinWidth' variable. ============================================================================== *taglist-commands* @@ -751,68 +894,107 @@ specified by the Tlist_WinWidth variable. The taglist plugin provides the following ex-mode commands: -|:Tlist| Open or close (toggle) the taglist window. -|:TlistAddFiles| Add multiple files to the taglist window. +|:TlistAddFiles| Add multiple files to the taglist. +|:TlistAddFilesRecursive| + Add files recursively to the taglist. |:TlistClose| Close the taglist window. |:TlistDebug| Start logging of taglist debug messages. +|:TlistLock| Stop adding new files to the taglist. |:TlistMessages| Display the logged taglist plugin debug messages. -|:TlistSessionSave| Save the information about files and tags displayed - in the taglist window to a session file. +|:TlistOpen| Open and jump to the taglist window. +|:TlistSessionSave| Save the information about files and tags in the + taglist to a session file. |:TlistSessionLoad| Load the information about files and tags stored - in a session file to the taglist window. -|:TlistShowPrototype| Display the prototype of the tag at or above the + in a session file to taglist. +|:TlistShowPrototype| Display the prototype of the tag at or before the specified line number. -|:TlistShowTag| Display the name of the tag defined at or above the - specified line number. -|:TlistSync| Highlight the current tag in the taglist window. +|:TlistShowTag| Display the name of the tag defined at or before the + specified line number. +|:TlistHighlightTag| Highlight the current tag in the taglist window. +|:TlistToggle| Open or close (toggle) the taglist window. |:TlistUndebug| Stop logging of taglist debug messages. +|:TlistUnlock| Start adding new files to the taglist. |:TlistUpdate| Update the tags for the current buffer. - *:Tlist* -:Tlist Open or close (toggle) the taglist window. Opens the taglist - window, if the window is not opened currently. Closes the - taglist window, if the taglist window is already opened. When - the taglist window is opened for the first time, all the files - in the buffer list are processed and the tags are displayed in - the taglist window. - *:TlistAddFiles* :TlistAddFiles {file(s)} [file(s) ...] - Process the tags defined in the specified file(s) and add them - to the taglist window. The files will not be edited and will - not be added to the Vim buffer list. You can specify - filenames using patterns. + Add one or more specified files to the taglist. You can + specify multiple filenames using wildcards. To specify a + file name with space character, you should escape the space + character with a backslash. + Examples: +> + :TlistAddFiles *.c *.cpp + :TlistAddFiles file1.html file2.html +< + If you specify a large number of files, then it will take some + time for the taglist plugin to process all of them. The + specified files will not be edited in a Vim window and will + not be added to the Vim buffer list. + + *:TlistAddFilesRecursive* +:TlistAddFilesRecursive {directory} [ {pattern} ] + Add files matching {pattern} recursively from the specified + {directory} to the taglist. If {pattern} is not specified, + then '*' is assumed. To specify the current directory, use "." + for {directory}. To specify a directory name with space + character, you should escape the space character with a + backslash. + Examples: +> + :TlistAddFilesRecursive myproject *.java + :TlistAddFilesRecursive smallproject +< + If large number of files are present in the specified + directory tree, then it will take some time for the taglist + plugin to process all of them. *:TlistClose* :TlistClose Close the taglist window. This command can be used from any one of the Vim windows. *:TlistDebug* -:TlistDebug +:TlistDebug [filename] Start logging of debug messages from the taglist plugin. - The debug messages are stored in a script local variable by - the taglist plugin. + If {filename} is specified, then the debug messages are stored + in the specified file. Otherwise, the debug messages are + stored in a script local variable. If the file {filename} is + already present, then it is overwritten. + + *:TlistLock* +:TlistLock + Lock the taglist and don't process new files. After this + command is executed, newly edited files will not be added to + the taglist. *:TlistMessages* :TlistMessages Display the logged debug messages from the taglist plugin. + This command works only when logging to a script-local + variable. + + *:TlistOpen* +:TlistOpen Open and jump to the taglist window. Creates the taglist + window, if the window is not opened currently. After executing + this command, the cursor is moved to the taglist window. When + the taglist window is opened for the first time, all the files + in the buffer list are processed and the tags defined in them + are displayed in the taglist window. *:TlistSessionSave* :TlistSessionSave {filename} - Save the information about files and tags displayed in the - taglist window to the specified file. This command can be used - to save and restore the taglist window contents across Vim - sessions. + Saves the information about files and tags in the taglist to + the specified file. This command can be used to save and + restore the taglist contents across Vim sessions. *:TlistSessionLoad* :TlistSessionLoad {filename} Load the information about files and tags stored in the - specified session file and update the taglist window with - the tags stored in the session file. + specified session file to the taglist. *:TlistShowPrototype* :TlistShowPrototype [filename] [linenumber] - Display the prototype of the tag at or below the specified + Display the prototype of the tag at or before the specified line number. If the file name and the line number are not specified, then the current file name and line number are used. A tag spans multiple lines starting from the line where @@ -822,31 +1004,46 @@ The taglist plugin provides the following ex-mode commands: *:TlistShowTag* :TlistShowTag [filename] [linenumber] - Display the name of the tag defined at or below the specified + Display the name of the tag defined at or before the specified line number. If the file name and the line number are not specified, then the current file name and line number are used. A tag spans multiple lines starting from the line where it is defined to the line before the next tag. This command displays the tag name for any line number in this range. - *:TlistSync* -:TlistSync Highlight the current tag in the taglist window. By default, + *:TlistHighlightTag* +:TlistHighlightTag + Highlight the current tag in the taglist window. By default, the taglist plugin periodically updates the taglist window to highlight the current tag. This command can be used to force the taglist plugin to highlight the current tag. + *:TlistToggle* +:TlistToggle Open or close (toggle) the taglist window. Opens the taglist + window, if the window is not opened currently. Closes the + taglist window, if the taglist window is already opened. When + the taglist window is opened for the first time, all the files + in the buffer list are processed and the tags are displayed in + the taglist window. After executing this command, the cursor + is not moved from the current window to the taglist window. + *:TlistUndebug* :TlistUndebug Stop logging of debug messages from the taglist plugin. + *:TlistUnlock* +:TlistUnlock + Unlock the taglist and start processing newly edited files. + *:TlistUpdate* -:TlistUpdate Update the tags displayed for the current buffer. This - command can be used to force an update of the tags for the - current file/buffer. As the taglist plugin uses the file saved - in the disk (instead of the file displayed in a Vim buffer), - you should save the modified buffer before you update the - taglist window. Otherwise the listed tags will not include the - new tags created in the buffer. +:TlistUpdate Update the tags information for the current buffer. This + command can be used to re-process the current file/buffer and + get the tags information. As the taglist plugin uses the file + saved in the disk (instead of the file displayed in a Vim + buffer), you should save a modified buffer before you update + the taglist. Otherwise the listed tags will not include the + new tags created in the buffer. You can use this command even + when the taglist window is not opened. ============================================================================== *taglist-functions* @@ -858,13 +1055,13 @@ described below. |Tlist_Update_File_Tags()| Update the tags for the specified file |Tlist_Get_Tag_Prototype_By_Line()| Return the prototype of the tag at or - below the specified line number in the + before the specified line number in the specified file. -|Tlist_Get_Tagname_By_Line()| Return the name of the tag at or below - the specified line number in the - specified file. -|Tlist_Set_App()| Set the name of the app controlling - the taglist window. +|Tlist_Get_Tagname_By_Line()| Return the name of the tag at or + before the specified line number in + the specified file. +|Tlist_Set_App()| Set the name of the application + controlling the taglist window. *Tlist_Update_File_Tags()* Tlist_Update_File_Tags({filename}, {filetype}) @@ -875,14 +1072,14 @@ Tlist_Update_File_Tags({filename}, {filetype}) *Tlist_Get_Tag_Prototype_By_Line()* Tlist_Get_Tag_Prototype_By_Line([{filename}, {linenumber}]) - Return the prototype of the tag at or below the specified + Return the prototype of the tag at or before the specified line number in the specified file. If the filename and line number are not specified, then the current buffer name and the current line number are used. *Tlist_Get_Tagname_By_Line()* Tlist_Get_Tagname_By_Line([{filename}, {linenumber}]) - Return the name of the tag at or below the specified line + Return the name of the tag at or before the specified line number in the specified file. If the filename and line number are not specified, then the current buffer name and the current line number are used. @@ -933,8 +1130,8 @@ in the buffer containing the file: > For example, to modify the support for the perl language files, you have to set the tlist_perl_settings variable. -The format of the value set in the tlist_xxx_settings variable is > - +The format of the value set in the tlist_xxx_settings variable is +> ;flag1:name1;flag2:name2;flag3:name3 < The different fields in the value are separated by the ';' character. @@ -954,8 +1151,8 @@ to use for displaying the tags of a particular type. For example, 'name' can be set to 'functions'. This field can be set to any text string name. For example, to list only the classes and functions defined in a C++ -language file, add the following lines to your .vimrc file > - +language file, add the following lines to your .vimrc file +> let tlist_cpp_settings = 'c++;c:class;f:function' < In the above setting, 'cpp' is the Vim filetype name and 'c++' is the name @@ -965,8 +1162,8 @@ used for the class tags and 'function' is the title used for the function tags in the taglist window. For example, to display only functions defined in a C file and to use "My -Functions" as the title for the function tags, use > - +Functions" as the title for the function tags, use +> let tlist_c_settings = 'c;f:My Functions' < When you set the tlist_xxx_settings variable, you will override the default @@ -996,20 +1193,34 @@ are generated for the flags b, c and l respectively. Q. The taglist plugin doesn't work. The taglist window is empty and the tags defined in a file are not displayed. A. Are you using Vim version 6.0 and above? The taglist plugin relies on the - features supported by Vim version 6.0 and above. - + features supported by Vim version 6.0 and above. You can use the following + command to get the Vim version: +> + $ vim --version +< Are you using exuberant ctags version 5.0 and above? The taglist plugin relies on the features supported by exuberant ctags and will not work with - GNU ctags or the Unix ctags utility. - + GNU ctags or the Unix ctags utility. You can use the following command to + determine whether the ctags installed in your system is exuberant ctags: +> + $ ctags --version +< Did you turn on the Vim filetype detection? The taglist plugin relies on the filetype detected by Vim and passes the filetype to the exuberant ctags - utility to parse the tags. Add the following line to the .vimrc or _vimrc - file to enable Vim filetype detection: > - + utility to parse the tags. Check the output of the following Vim command: +> + :filetype +< + To turn on the filetype detection, add the following line to the .vimrc or + _vimrc file: +> filetype on < Is your version of Vim compiled with the support for the system() function? + The following Vim command should display 1: +> + :echo exists('*system') +< In some Linux distributions (particularly Suse Linux), the default Vim installation is built without the support for the system() function. The taglist plugin uses the system() function to invoke the exuberant ctags @@ -1017,8 +1228,8 @@ A. Are you using Vim version 6.0 and above? The taglist plugin relies on the system() function. If you use the default build options, the system() function will be supported. - Do you have the |shellslash| option set? You can try disabling the - |shellslash| option. When the taglist plugin invokes the exuberant ctags + Do you have the |'shellslash'| option set? You can try disabling the + |'shellslash'| option. When the taglist plugin invokes the exuberant ctags utility with the path to the file, if the incorrect slashes are used, then you will see errors. @@ -1033,9 +1244,9 @@ A. Are you using Vim version 6.0 and above? The taglist plugin relies on the Run the following command from the shell and see whether you see your tags in the output from exuberant ctags: - - ctags -f - --format=2 --excmd=pattern --fields=nks - +> + ctags -f - --format=2 --excmd=pattern --fields=nks +< If you see your tags in the output from the above command, then the exuberant ctags utility is properly parsing your file. @@ -1051,13 +1262,19 @@ A. Are you using Vim version 6.0 and above? The taglist plugin relies on the name. For example, if the temporary directory name is "C:\Documents and Settings\xyz\Local Settings\Temp", then try setting the TEMP variable to the following: - +> set TEMP=C:\DOCUMEN~1\xyz\LOCALS~1\Temp - +< If exuberant ctags is installed in a directory with space characters in the name, then try adding the directory to the PATH environment variable or try - copying the exuberant ctags to a path without space characters in the name. - + setting the 'Tlist_Ctags_Cmd' variable to the shortest path name to ctags + or try copying the exuberant ctags to a path without space characters in + the name. For example, if exuberant ctags is installed in the directory + "C:\Program Files\Ctags", then try setting the 'Tlist_Ctags_Cmd' variable + as below: +> + let Tlist_Ctags_Cmd='C:\Progra~1\Ctags\ctags.exe' +< Q. When I try to open the taglist window, I am seeing the following error message. How do I fix this problem? @@ -1069,7 +1286,7 @@ A. The taglist plugin will work only with the exuberant ctags tool. You You will see an error message similar to the one shown above, if you try use a non-exuberant ctags program with Vim. To fix this problem, either add the exuberant ctags tool location to the PATH environment variable or set - the Tlist_Ctags_Cmd variable. + the 'Tlist_Ctags_Cmd' variable. Q. A file has more than one tag with the same name. When I select a tag name from the taglist window, the cursor is positioned at the incorrect tag @@ -1089,7 +1306,7 @@ A. The exuberant ctags utility will process only files that are present in the Q. I have created a ctags file using the exuberant ctags utility for my source tree. How do I configure the taglist plugin to use this tags file? -A. The taglist plugin doesn't a tags file stored in disk. For every opened +A. The taglist plugin doesn't use a tags file stored in disk. For every opened file, the taglist plugin invokes the exuberant ctags utility to get the list of tags dynamically. The Vim system() function is used to invoke exuberant ctags and get the ctags output. This function internally uses a @@ -1097,17 +1314,17 @@ A. The taglist plugin doesn't a tags file stored in disk. For every opened from the command is read. So you will never see the file that contains the output of exuberant ctags. -Q. When I set the |updatetime| option to a low value (less than 1000) and if I - keep pressing a key with the taglist window open, the current buffer +Q. When I set the |'updatetime'| option to a low value (less than 1000) and if + I keep pressing a key with the taglist window open, the current buffer contents are changed. Why is this? A. The taglist plugin uses the |CursorHold| autocmd to highlight the current - tag. The CursorHold autocmd triggers for every 'updatetime' milliseconds. - If the 'updatetime' option is set to a low value, then the CursorHold + tag. The CursorHold autocmd triggers for every |'updatetime'| milliseconds. + If the |'updatetime'| option is set to a low value, then the CursorHold autocmd will be triggered frequently. As the taglist plugin changes the focus to the taglist window to highlight the current tag, this could interfere with the key movement resulting in changing the contents of the current buffer. The workaround for this problem is to not set the - 'updatetime' option to a low value. + |'updatetime'| option to a low value. ============================================================================== *taglist-todo* @@ -1118,12 +1335,9 @@ A. The taglist plugin uses the |CursorHold| autocmd to highlight the current 2. Support for displaying tags in a modified (not-yet-saved) file. 3. Automatically open the taglist window only for selected filetypes. For other filetypes, close the taglist window. -4. Taglist plugin doesn't work properly with the Vim session support. - When a session with taglist window is saved and restored, the plugin - doesn't update the window. -5. When using the shell from the MKS toolkit, the taglist plugin +4. When using the shell from the MKS toolkit, the taglist plugin doesn't work. -6. The taglist plugin doesn't work with files edited remotely using the +5. The taglist plugin doesn't work with files edited remotely using the netrw plugin. The exuberant ctags utility cannot process files over scp/rcp/ftp, etc. diff --git a/plugin/taglist.vim b/plugin/taglist.vim index 901b5be..d58420c 100644 --- a/plugin/taglist.vim +++ b/plugin/taglist.vim @@ -1,7 +1,7 @@ " File: taglist.vim " Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) -" Version: 4.0 Beta 2 -" Last Modified: July 21, 2005 +" Version: 4.0 Beta 3 +" Last Modified: Dec 28, 2005 " " 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 @@ -42,164 +42,290 @@ " 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 ":Tlist" command to open/close the taglist +" 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 ************************ -" -if exists('loaded_taglist') - finish -endif -let loaded_taglist='yes' " Line continuation used here let s:cpo_save = &cpo set cpo&vim -" 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.' +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') + let Tlist_Ctags_Cmd = 'exuberant-ctags' + 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 + + " 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_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 TlistToggle call s:Tlist_Window_Toggle() + command! -nargs=0 TlistOpen call s:Tlist_Window_Open() + " For backwards compatiblity define the Tlist command + command! -nargs=0 Tlist TlistToggle + command! -nargs=+ -complete=file TlistAddFiles + \ call s:Tlist_Add_Files() + command! -nargs=+ -complete=dir TlistAddFilesRecursive + \ call s:Tlist_Add_Files_Recursive() + command! -nargs=0 TlistClose call s:Tlist_Window_Close() + command! -nargs=0 TlistUpdate call s:Tlist_Update_Current_File() + command! -nargs=0 TlistHighlightTag call s:Tlist_Highlight_Tag( + \ fnamemodify(bufname('%'), ':p'), line('.'), 2, 1) + " For backwards compatiblity define the TlistSync command + command! -nargs=0 TlistSync TlistHighlightTag + command! -nargs=* -complete=buffer TlistShowPrototype + \ echo Tlist_Get_Tag_Prototype_By_Line() + command! -nargs=* -complete=buffer TlistShowTag + \ echo Tlist_Get_Tagname_By_Line() + command! -nargs=* -complete=file TlistSessionLoad + \ call s:Tlist_Session_Load() + command! -nargs=* -complete=file TlistSessionSave + \ call s:Tlist_Session_Save() + command! TlistLock let Tlist_Auto_Update=0 + command! TlistUnlock let Tlist_Auto_Update=1 + + " Commands for enabling/disabling debug and to display debug messages + command! -nargs=? -complete=file TlistDebug + \ call s:Tlist_Debug_Enable() + command! -nargs=0 TlistUndebug call s:Tlist_Debug_Disable() + command! -nargs=0 TlistMessages echo s:tlist_msg + + " Define autocommands to autoload the taglist plugin when needed. + + " Trick to get the current script ID + map xx xx + let s:sid = substitute(maparg('xx'), '\(\d\+_\)xx$', '\1', '') + unmap xx + + exe 'autocmd FuncUndefined *' . s:sid . 'Tlist_* source ' . + \ expand('') + exe 'autocmd FuncUndefined Tlist_* source ' . expand('') + exe 'autocmd FuncUndefined TagList_* source ' . expand('') + + unlet! s:sid + + let loaded_taglist = 'fast_load_done' + + " restore 'cpo' let &cpo = s:cpo_save finish endif -" Location of the exuberant ctags tool -if !exists('Tlist_Ctags_Cmd') - if executable('exuberant-ctags') - let Tlist_Ctags_Cmd = 'exuberant-ctags' - 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 &cpo = s:cpo_save - finish - endif +if loaded_taglist != 'fast_load_done' + " restore 'cpo' + let &cpo = s:cpo_save + finish endif " Taglist plugin functionality is available let loaded_taglist = 'available' -" 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 - -" Automatically open the taglist window on Vim startup -if !exists('Tlist_Auto_Open') - let Tlist_Auto_Open = 0 -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 - -" Automatically highlight the current tag -if !exists('Tlist_Auto_Highlight_Tag') - let Tlist_Auto_Highlight_Tag = 1 -endif - -" Process files even when the taglist window is not open -if !exists('Tlist_Process_File_Always') - let Tlist_Process_File_Always = 0 -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_Show_Menu') - let Tlist_Show_Menu = 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 - "------------------- end of user configurable options -------------------- -" Initialize the taglist plugin local variables for the supported file types -" and tag types +" 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 - 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' @@ -221,8 +347,8 @@ 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++;v:variable;d:macro;t:typedef;c:class;' . - \ 'n:namespace;g:enum;s:struct;u:union;f:function' +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;' . @@ -333,7 +459,9 @@ let s:tlist_def_yacc_settings = 'yacc;l:label' let s:tlist_winsize_chgd = 0 " Taglist window is maximized or not let s:tlist_win_maximized = 0 -" Number of files displayed in the taglist window +" 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 @@ -343,12 +471,10 @@ let s:tlist_app_name = "none" 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 -" 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__" " 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 @@ -441,25 +567,58 @@ function! s:Tlist_Toggle_Help_Text() endfunction " Taglist debug support -let s:tlist_msg = '' let s:tlist_debug = 0 -" Commands for enabling/disabling debug and to display debug messages -command! -nargs=0 TlistDebug let s:tlist_debug = 1 -command! -nargs=0 TlistUndebug let s:tlist_debug = 0 -command! -nargs=0 TlistMessages echo s:tlist_msg +" 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_Log_Msg " Log the supplied debug message along with the time function! s:Tlist_Log_Msg(msg) if s:tlist_debug - " 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) + 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 - let s:tlist_msg = s:tlist_msg . strftime('%H:%M:%S') . ': ' . - \ a:msg . "\n" endif endfunction @@ -471,38 +630,99 @@ function! s:Tlist_Warning_Msg(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) - let i = 0 + if s:tlist_file_count == 0 + return -1 + endif - " Do a linear search - while i < s:tlist_file_count - if s:tlist_{i}_filename == a:fname - return i + " 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 - let i = i + 1 - endwhile + endif - return -1 + " 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_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_Get_File_Index_By_Linenum(lnum) call s:Tlist_Log_Msg('Tlist_Get_File_Index_By_Linenum (' . a:lnum . ')') - let i = 0 - " TODO: Convert this to a binary search - while i < s:tlist_file_count - if a:lnum >= s:tlist_{i}_start && a:lnum <= s:tlist_{i}_end - return i + " 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 + + " 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 - let i = i + 1 endwhile - return -1 + if left < 0 || left >= s:tlist_file_count || + \ a:lnum < s:tlist_{left}_start || a:lnum > s:tlist_{left}_end + let fidx = -1 + else + let fidx = left + 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() @@ -666,6 +886,56 @@ function! s:Tlist_FileType_Init(ftype) return 1 endfunction +" Tlist_Get_Filetype +" Determine the filetype for the specified file +function! s:Tlist_Get_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) + if bufloaded(a:bnum) + " For loaded buffers, the 'filetype' is already determined + return getbufvar(a:bnum, '&filetype') + endif + + " For unloaded buffers, if the 'filetype' option is set, return it + let ftype = getbufvar(a:bnum, '&filetype') + if ftype != '' + return ftype + 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_Get_Filetype(bname) +endfunction + " Tlist_Discard_TagInfo " Discard the stored tag information for a file function! s:Tlist_Discard_TagInfo(fidx) @@ -689,14 +959,14 @@ function! s:Tlist_Discard_TagInfo(fidx) let s:tlist_{a:fidx}_tag_count = 0 - " Discard information about tags groups by their type + " 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}_start = 0 + let {fidx_ttype}_offset = 0 let cnt = {fidx_ttype}_count let {fidx_ttype}_count = 0 let j = 1 @@ -746,7 +1016,7 @@ function! s:Tlist_Discard_FileInfo(fidx) while i <= s:tlist_{ftype}_count let ttype = s:tlist_{ftype}_{i}_name unlet! s:tlist_{a:fidx}_{ttype} - unlet! s:tlist_{a:fidx}_{ttype}_start + unlet! s:tlist_{a:fidx}_{ttype}_offset unlet! s:tlist_{a:fidx}_{ttype}_count let i = i + 1 endwhile @@ -806,14 +1076,41 @@ function! s:Tlist_Remove_File(file_idx, user_request) call s:Tlist_Log_Msg('Tlist_Remove_File (' . \ s:tlist_{fidx}_filename . ', ' . a:user_request . ')') - call s:Tlist_Remove_File_From_Display(fidx) + let save_winnr = winnr() + let winnum = bufwinnr(g:TagList_title) + if winnum != -1 + " Taglist window is open, remove the file from display + + if save_winnr != winnum + let old_eventignore = &eventignore + set eventignore=all + exe winnum . 'wincmd w' + endif + + call s:Tlist_Remove_File_From_Display(fidx) + + if save_winnr != winnum + exe save_winnr . 'wincmd w' + let &eventignore = old_eventignore + endif + endif + + let fname = s:tlist_{fidx}_filename if a:user_request " As the user requested to remove the file from taglist, " add it to the removed list - call s:Tlist_Update_Remove_List(s:tlist_{fidx}_filename, 1) + call s:Tlist_Update_Remove_List(fname, 1) endif + " Remove the file name from the taglist list of filenames + let idx = stridx(s:tlist_file_names, fname . "\n") + let text_before = strpart(s:tlist_file_names, 0, idx) + let rem_text = strpart(s:tlist_file_names, idx) + let next_idx = stridx(rem_text, "\n") + let text_after = strpart(rem_text, next_idx + 1) + let s:tlist_file_names = text_before . text_after + call s:Tlist_Discard_FileInfo(fidx) " Shift all the file variables by one index @@ -837,7 +1134,7 @@ function! s:Tlist_Remove_File(file_idx, user_request) while k <= s:tlist_{j}_tag_count let s:tlist_{j}_{k}_tag = s:tlist_{i}_{k}_tag let s:tlist_{j}_{k}_tag_name = s:tlist_{i}_{k}_tag_name - let s:tlist_{j}_{k}_tag_type = s:Tlist_Get_Tag_Type(i, k) + let s:tlist_{j}_{k}_tag_type = s:Tlist_Get_Tag_Type_By_Tag(i, k) let s:tlist_{j}_{k}_ttype_idx = s:tlist_{i}_{k}_ttype_idx let s:tlist_{j}_{k}_tag_proto = s:Tlist_Get_Tag_Prototype(i, k) let s:tlist_{j}_{k}_tag_searchpat = s:Tlist_Get_Tag_SearchPat(i, k) @@ -851,7 +1148,7 @@ function! s:Tlist_Remove_File(file_idx, user_request) while k <= s:tlist_{ftype}_count let ttype = s:tlist_{ftype}_{k}_name let s:tlist_{j}_{ttype} = s:tlist_{i}_{ttype} - let s:tlist_{j}_{ttype}_start = s:tlist_{i}_{ttype}_start + let s:tlist_{j}_{ttype}_offset = s:tlist_{i}_{ttype}_offset let s:tlist_{j}_{ttype}_count = s:tlist_{i}_{ttype}_count if s:tlist_{j}_{ttype} != '' let l = 1 @@ -874,19 +1171,29 @@ function! s:Tlist_Remove_File(file_idx, user_request) let s:tlist_file_count = s:tlist_file_count - 1 if g:Tlist_Show_One_File - " If the tags for only one file are displayed and if we just - " now removed the file, then invalidate the current file idx + " If the tags for only one file is displayed and if we just + " now removed that file, then invalidate the current file idx if s:tlist_cur_file_idx == fidx let s:tlist_cur_file_idx = -1 endif endif endfunction +" Tlist_Goto_Window +" Goto the taglist window +function! s:Tlist_Goto_Window() + let winnum = bufwinnr(g:TagList_title) + if winnum != -1 + if winnr() != winnum + call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w') + endif + endif +endfunction -" Tlist_Open_Window +" Tlist_Window_Create " Create a new taglist window. If it is already open, jump to it -function! s:Tlist_Open_Window() - call s:Tlist_Log_Msg('Tlist_Open_Window()') +function! s:Tlist_Window_Create() + call s:Tlist_Log_Msg('Tlist_Window_Create()') " If the window is open, jump to it let winnum = bufwinnr(g:TagList_title) if winnum != -1 @@ -912,7 +1219,7 @@ function! s:Tlist_Open_Window() " Horizontal window height let win_size = g:Tlist_WinHeight else - " Open a horizontally split window. Increase the window size, if + " Open a vertically split window. Increase the window size, if " needed, to accomodate the new window if g:Tlist_Inc_Winwidth && \ &columns < (80 + g:Tlist_WinWidth) @@ -957,12 +1264,12 @@ function! s:Tlist_Open_Window() let s:tlist_winy = getwinposy() " Initialize the taglist window - call s:Tlist_Init_Window() + call s:Tlist_Window_Init() endfunction -" Tlist_Zoom_Window +" Tlist_Window_Zoom " Zoom (maximize/minimize) the taglist window -function! s:Tlist_Zoom_Window() +function! s:Tlist_Window_Zoom() if s:tlist_win_maximized " Restore the window back to the previous size if g:Tlist_Use_Horiz_Window @@ -983,12 +1290,12 @@ function! s:Tlist_Zoom_Window() endif endfunction -" Tlist_Check_Window_Size +" Tlist_Window_Check_Width " Check the width of the taglist window. For horizontally split windows, the " 'winfixheight' option is used to fix the height of the window. For " vertically split windows, Vim doesn't support the 'winfixwidth' option. So " need to handle window width changes from this function. -function! s:Tlist_Check_Window_Width() +function! s:Tlist_Window_Check_Width() let tlist_winnr = bufwinnr(g:TagList_title) if tlist_winnr == -1 return @@ -996,23 +1303,23 @@ function! s:Tlist_Check_Window_Width() let width = winwidth(tlist_winnr) if width != g:Tlist_WinWidth - call s:Tlist_Log_Msg("Tlist_Check_Window_Width: Changing window " . - \ "width from " . width . "to " . g:Tlist_WinWidth) + call s:Tlist_Log_Msg("Tlist_Window_Check_Width: Changing window " . + \ "width from " . width . " to " . g:Tlist_WinWidth) let save_winnr = winnr() if save_winnr != tlist_winnr - exe tlist_winnr . 'wincmd w' + call s:Tlist_Exe_Cmd_No_Acmds(tlist_winnr . 'wincmd w') endif exe 'vert resize ' . g:Tlist_WinWidth if save_winnr != tlist_winnr - wincmd p + call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') endif endif endfunction -" Tlist_Init_Window +" Tlist_Window_Init " Set the default options for the taglist window -function! s:Tlist_Init_Window() - call s:Tlist_Log_Msg('Tlist_Init_Window()') +function! s:Tlist_Window_Init() + call s:Tlist_Log_Msg('Tlist_Window_Init()') " Define taglist window element highlighting syntax match TagListComment '^" .*' syntax match TagListFileName '^[^" ].*$' @@ -1027,41 +1334,43 @@ function! s:Tlist_Init_Window() if hlexists('MyTagListTagName') highlight link TagListTagName MyTagListTagName else - highlight link TagListTagName Search + highlight default link TagListTagName Search endif " Colors to highlight comments and titles if hlexists('MyTagListComment') highlight link TagListComment MyTagListComment else highlight clear TagListComment - highlight link TagListComment Comment + highlight default link TagListComment Comment endif if hlexists('MyTagListTitle') highlight link TagListTitle MyTagListTitle else highlight clear TagListTitle - highlight link TagListTitle Title + highlight default link TagListTitle Title endif if hlexists('MyTagListFileName') highlight link TagListFileName MyTagListFileName else highlight clear TagListFileName - highlight link TagListFileName LineNr + highlight default TagListFileName guibg=darkgray ctermbg=darkgray + \ guifg=white ctermfg=white endif if hlexists('MyTagListTagScope') highlight link TagListTagScope MyTagListTagScope else highlight clear TagListTagScope - highlight link TagListTagScope Identifier + highlight default link TagListTagScope Identifier endif else - highlight TagListTagName term=reverse cterm=reverse + highlight default TagListTagName term=reverse cterm=reverse endif " Folding related settings setlocal foldenable setlocal foldminlines=0 setlocal foldmethod=manual + setlocal foldlevel=9999 if g:Tlist_Enable_Fold_Column setlocal foldcolumn=3 else @@ -1115,10 +1424,10 @@ function! s:Tlist_Init_Window() nnoremap :silent! foldopen nnoremap :silent! foldclose nnoremap :silent! %foldopen! - nnoremap :call Tlist_Show_Tag_Prototype() - nnoremap u :call Tlist_Update_Window() + nnoremap :call Tlist_Show_Info() + nnoremap u :call Tlist_Window_Update_File() nnoremap d :call Tlist_Remove_File(-1, 1) - nnoremap x :call Tlist_Zoom_Window() + nnoremap x :call Tlist_Window_Zoom() nnoremap [[ :call Tlist_Move_To_File(-1) nnoremap :call Tlist_Move_To_File(-1) nnoremap ]] :call Tlist_Move_To_File(1) @@ -1144,10 +1453,11 @@ function! s:Tlist_Init_Window() inoremap :silent! foldclose inoremap :silent! %foldopen! inoremap :call - \ Tlist_Show_Tag_Prototype() - inoremap u :call Tlist_Update_Window() + \ Tlist_Show_Info() + inoremap u + \ :call Tlist_Window_Update_File() inoremap d :call Tlist_Remove_File(-1, 1) - inoremap x :call Tlist_Zoom_Window() + inoremap x :call Tlist_Window_Zoom() inoremap [[ :call Tlist_Move_To_File(-1) inoremap :call Tlist_Move_To_File(-1) inoremap ]] :call Tlist_Move_To_File(1) @@ -1158,31 +1468,31 @@ function! s:Tlist_Init_Window() " Map single left mouse click if the user wants this functionality if g:Tlist_Use_SingleClick == 1 " Contributed by Bindu Wavell - " attempt to perform single click mapping, it would be much - " nicer if we could nnoremap ... however vim does - " not fire the when you use the mouse - " to enter a buffer. - let clickmap = ':if bufname("%") =~ "__Tag_List__" ' . - \ 'call Tlist_Jump_To_Tag(0) endif ' - if maparg('', 'n') == '' - " no mapping for leftmouse - exe ':nnoremap ' . clickmap - else - " we have a mapping - let mapcmd = ':nnoremap ' - let mapcmd = mapcmd . substitute(substitute( - \ maparg('', 'n'), '|', '', 'g'), - \ '\c^', '', '') - let mapcmd = mapcmd . clickmap - exe mapcmd - endif + " attempt to perform single click mapping, it would be much + " nicer if we could nnoremap ... however vim does + " not fire the when you use the mouse + " to enter a buffer. + let clickmap = ':if bufname("%") =~ "__Tag_List__" ' . + \ 'call Tlist_Jump_To_Tag(0) endif ' + if maparg('', 'n') == '' + " no mapping for leftmouse + exe ':nnoremap ' . clickmap + else + " we have a mapping + let mapcmd = ':nnoremap ' + let mapcmd = mapcmd . substitute(substitute( + \ maparg('', 'n'), '|', '', 'g'), + \ '\c^', '', '') + let mapcmd = mapcmd . clickmap + exe mapcmd + endif endif " Define the taglist autocommands augroup TagListAutoCmds autocmd! " Display the tag prototype for the tag under the cursor. - autocmd CursorHold __Tag_List__ call s:Tlist_Show_Tag_Prototype() + autocmd CursorHold __Tag_List__ call s:Tlist_Show_Info() " Highlight the current tag periodically autocmd CursorHold * silent call s:Tlist_Highlight_Tag( \ fnamemodify(bufname('%'), ':p'), line('.'), 1, 0) @@ -1191,15 +1501,15 @@ function! s:Tlist_Init_Window() autocmd BufUnload __Tag_List__ call s:Tlist_Post_Close_Cleanup() " Close the fold for this buffer when it's not visible in any window if g:Tlist_File_Fold_Auto_Close - autocmd BufWinLeave * silent call s:Tlist_Update_File_Display( - \ fnamemodify(expand(''), ':p'), 1) + autocmd BufWinLeave * silent + \ call s:Tlist_Close_File_Fold(expand(':p')) endif - " Remove the file from the list when it's buffer is deleted - autocmd BufDelete * silent call s:Tlist_Update_File_Display( - \ fnamemodify(expand(''), ':p'), 2) " Exit Vim itself if only the taglist window is present (optional) if g:Tlist_Exit_OnlyWindow - autocmd BufEnter __Tag_List__ if winbufnr(2) == -1 | quit | endif + " Before quitting Vim, delete the taglist buffer so that + " the '0 mark is correctly set to the previous buffer. + autocmd BufEnter __Tag_List__ nested if winbufnr(2) == -1 | + \ bdelete | quit | endif endif if s:tlist_app_name != "winmanager" && \ !g:Tlist_Process_File_Always && @@ -1209,7 +1519,7 @@ function! s:Tlist_Init_Window() endif if !g:Tlist_Use_Horiz_Window - autocmd WinEnter * call s:Tlist_Check_Window_Width() + autocmd WinEnter * call s:Tlist_Window_Check_Width() endif augroup end @@ -1217,10 +1527,10 @@ function! s:Tlist_Init_Window() let &cpoptions = old_cpoptions endfunction -" Tlist_Refresh_Window +" Tlist_Window_Refresh " Display the tags for all the files in the taglist window -function! s:Tlist_Refresh_Window() - call s:Tlist_Log_Msg('Tlist_Refresh_Window()') +function! s:Tlist_Window_Refresh() + call s:Tlist_Log_Msg('Tlist_Window_Refresh()') " Set report option to a huge value to prevent informational messages " while deleting the lines let old_report = &report @@ -1264,16 +1574,36 @@ function! s:Tlist_Refresh_Window() " tags for the wrong file will be displayed. let i = 0 while i < s:tlist_file_count - call s:Tlist_Explore_File(s:tlist_{i}_filename, s:tlist_{i}_filetype) + call s:Tlist_Window_Refresh_File(s:tlist_{i}_filename, + \ s:tlist_{i}_filetype) let i = i + 1 endwhile - " If Tlist_File_Fold_Auto_Close option is set, then close all the - " folds + if g:Tlist_Auto_Update + " Add and list the tags for all buffers in the Vim buffer list + let i = 1 + let last_bufnum = bufnr('$') + while i <= last_bufnum + if buflisted(i) + let fname = fnamemodify(bufname(i), ':p') + let ftype = s:Tlist_Get_Buffer_Filetype(i) + " If the file doesn't support tag listing, skip it + if !s:Tlist_Skip_File(fname, ftype) + call s:Tlist_Window_Refresh_File(fname, ftype) + endif + endif + let i = i + 1 + endwhile + endif + + " If Tlist_File_Fold_Auto_Close option is set, then close all the folds if g:Tlist_File_Fold_Auto_Close " Close all the folds silent! %foldclose endif + + " Move the cursor to the top of the taglist window + normal! gg endfunction " Tlist_Post_Close_Cleanup() @@ -1328,14 +1658,14 @@ function! s:Tlist_Post_Close_Cleanup() " Reset taglist state variables if s:tlist_app_name == "winmanager" let s:tlist_app_name = "none" - let s:tlist_window_initialized = 0 endif + let s:tlist_window_initialized = 0 endfunction -" Tlist_Explore_File() +" Tlist_Window_Refresh_File() " List the tags defined in the specified file in a Vim window -function! s:Tlist_Explore_File(filename, ftype) - call s:Tlist_Log_Msg('Tlist_Explore_File (' . a:filename . ')') +function! s:Tlist_Window_Refresh_File(filename, ftype) + call s:Tlist_Log_Msg('Tlist_Window_Refresh_File (' . a:filename . ')') " First check whether the file already exists let fidx = s:Tlist_Get_File_Index(a:filename) if fidx != -1 @@ -1449,7 +1779,7 @@ function! s:Tlist_Explore_File(filename, ftype) endif silent! put =ttype_txt - let {fidx_ttype}_start = ttype_start_lnum - file_start + let {fidx_ttype}_offset = ttype_start_lnum - file_start " create a fold for this tag type let fold_start = ttype_start_lnum @@ -1479,8 +1809,10 @@ function! s:Tlist_Explore_File(filename, ftype) " Create a fold for the entire file exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'fold' - exe 'silent! ' . s:tlist_{fidx}_start . ',' . - \ s:tlist_{fidx}_end . 'foldopen!' + if !g:Tlist_File_Fold_Auto_Close + exe 'silent! ' . s:tlist_{fidx}_start . ',' . + \ s:tlist_{fidx}_end . 'foldopen!' + endif " Goto the starting line for this file, exe s:tlist_{fidx}_start @@ -1522,6 +1854,8 @@ function! s:Tlist_Init_File(filename, ftype) " Add new files at the end of the list let fidx = s:tlist_file_count let s:tlist_file_count = s:tlist_file_count + 1 + " Add the new file name to the taglist list of file names + let s:tlist_file_names = s:tlist_file_names . a:filename . "\n" " Initialize the file variables let s:tlist_{fidx}_filename = a:filename @@ -1540,7 +1874,7 @@ function! s:Tlist_Init_File(filename, ftype) while i <= s:tlist_{a:ftype}_count let ttype = s:tlist_{a:ftype}_{i}_name let s:tlist_{fidx}_{ttype} = '' - let s:tlist_{fidx}_{ttype}_start = 0 + let s:tlist_{fidx}_{ttype}_offset = 0 let s:tlist_{fidx}_{ttype}_count = 0 let i = i + 1 endwhile @@ -1548,8 +1882,9 @@ function! s:Tlist_Init_File(filename, ftype) return fidx endfunction -" Tlist_Get_Tag_Type -function! s:Tlist_Get_Tag_Type(fidx, tidx) +" Tlist_Get_Tag_Type_By_Tag +" Return the tag type for the specified tag index +function! s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx) let ttype_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_type' " Already parsed and have the tag name @@ -1608,7 +1943,7 @@ function! s:Tlist_Get_Tag_SearchPat(fidx, tidx) endfunction " Tlist_Get_Tag_Linenum -" Return the tag line number +" Return the tag line number, given the tag index function! s:Tlist_Get_Tag_Linenum(fidx, tidx) let tline_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_linenum' @@ -1901,10 +2236,10 @@ function! s:Tlist_Process_File(filename, ftype) return fidx endfunction -" Tlist_Update_File_Tags +" Tlist_Update_File " Update the tags for a file (if needed) -function! Tlist_Update_File_Tags(filename, ftype) - call s:Tlist_Log_Msg('Tlist_Update_File_Tags (' . a:filename . ')') +function! Tlist_Update_File(filename, ftype) + call s:Tlist_Log_Msg('Tlist_Update_File (' . a:filename . ')') " If the file doesn't support tag listing, skip it if s:Tlist_Skip_File(a:filename, a:ftype) return @@ -1952,14 +2287,26 @@ function! Tlist_Update_File_Tags(filename, ftype) let save_winnr = winnr() " Goto the taglist window - call s:Tlist_Open_Window() + call s:Tlist_Goto_Window() + + " Save the cursor position + let save_line = line('.') + let save_col = col('.') " Update the taglist window - call s:Tlist_Explore_File(fname, a:ftype) + call s:Tlist_Window_Refresh_File(fname, a:ftype) + + " Restore the cursor position + if v:version >= 601 + call cursor(save_line, save_col) + else + exe save_line + exe 'normal! ' . save_col . '|' + endif if winnr() != save_winnr " Go back to the original window - exe save_winnr . 'wincmd w' + call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w') endif endif @@ -1969,10 +2316,10 @@ function! Tlist_Update_File_Tags(filename, ftype) endif endfunction -" Tlist_Close_Window +" Tlist_Window_Close " Close the taglist window -function! s:Tlist_Close_Window() - call s:Tlist_Log_Msg('Tlist_Close_Window()') +function! s:Tlist_Window_Close() + call s:Tlist_Log_Msg('Tlist_Window_Close()') " Make sure the taglist window exists let winnum = bufwinnr(g:TagList_title) if winnum == -1 @@ -2002,14 +2349,17 @@ function! s:Tlist_Close_Window() endif endfunction -" Tlist_Toggle_Window() -" Open or close a taglist window -function! s:Tlist_Toggle_Window() - call s:Tlist_Log_Msg('Tlist_Toggle_Window()') - " If taglist window is open then close it. +" Tlist_Window_Open +" Open and refresh the taglist window +function! s:Tlist_Window_Open() + call s:Tlist_Log_Msg('Tlist_Window_Open()') + " If the window is open, jump to it let winnum = bufwinnr(g:TagList_title) if winnum != -1 - call s:Tlist_Close_Window() + " Jump to the existing window + if winnr() != winnum + exe winnum . 'wincmd w' + endif return endif @@ -2024,46 +2374,52 @@ function! s:Tlist_Toggle_Window() let cur_lnum = line('.') " Mark the current window as the desired window to open a file - " when a tag is selcted + " when a tag is selected let w:tlist_file_window = "yes" " Open the taglist window - call s:Tlist_Open_Window() + call s:Tlist_Window_Create() - call s:Tlist_Refresh_Window() + call s:Tlist_Window_Refresh() if g:Tlist_Show_One_File " Add only the current buffer and file " " If the file doesn't support tag listing, skip it if !s:Tlist_Skip_File(curbuf_name, curbuf_ftype) - call s:Tlist_Explore_File(curbuf_name, curbuf_ftype) + call s:Tlist_Window_Refresh_File(curbuf_name, curbuf_ftype) + endif + endif + + if g:Tlist_File_Fold_Auto_Close + " Open the fold for the current file, as all the folds in + " the taglist window are closed + let fidx = s:Tlist_Get_File_Index(curbuf_name) + if fidx != -1 + exe "silent! " . s:tlist_{fidx}_start . "," . + \ s:tlist_{fidx}_end . "foldopen!" endif - else - " Add and list the tags for all loaded buffers in the Vim buffer list - let i = 1 - let last_bufnum = bufnr('$') - while i <= last_bufnum - if bufexists(i) && bufloaded(i) - let fname = fnamemodify(bufname(i), ':p') - let ftype = getbufvar(i, '&filetype') - " If the file doesn't support tag listing, skip it - if !s:Tlist_Skip_File(fname, ftype) - call s:Tlist_Explore_File(fname, ftype) - endif - endif - let i = i + 1 - endwhile endif " Highlight the current tag call s:Tlist_Highlight_Tag(curbuf_name, cur_lnum, 1, 1) +endfunction + +" Tlist_Window_Toggle() +" Open or close a taglist window +function! s:Tlist_Window_Toggle() + call s:Tlist_Log_Msg('Tlist_Window_Toggle()') + " If taglist window is open then close it. + let winnum = bufwinnr(g:TagList_title) + if winnum != -1 + call s:Tlist_Window_Close() + return + endif + + call s:Tlist_Window_Open() " Go back to the original window - let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh - let s:Tlist_Skip_Refresh = 1 - wincmd p - let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh + call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') " Update the taglist menu if g:Tlist_Show_Menu @@ -2071,6 +2427,76 @@ function! s:Tlist_Toggle_Window() endif endfunction +" Tlist_Process_Dir +" Process the files in a directory matching the specified pattern +function! s:Tlist_Process_Dir(dir_name, pat) + let flist = glob(a:dir_name . '/' . a:pat) . "\n" + + " Process one file at a time + while flist != '' + let nl_idx = stridx(flist, "\n") + let one_file = strpart(flist, 0, nl_idx) + + let flist = strpart(flist, nl_idx + 1) + + if one_file == '' + continue + endif + + if !isdirectory(one_file) + let ftype = s:Tlist_Get_Filetype(one_file) + + echon "\r " + echon "\rProcessing tags for " . fnamemodify(one_file, ':p:t') + + silent call Tlist_Update_File(one_file, ftype) + endif + endwhile + + let all_files = glob(a:dir_name . '/*') . "\n" + while all_files != '' + let nl_idx = stridx(all_files, "\n") + let one_file = strpart(all_files, 0, nl_idx) + + let all_files = strpart(all_files, nl_idx + 1) + if one_file == '' + continue + endif + + if !isdirectory(one_file) + continue + endif + + call s:Tlist_Process_Dir(one_file, a:pat) + endwhile +endfunction + +" Tlist_Add_Files_Recursive +" Add files recursively from a directory +function! s:Tlist_Add_Files_Recursive(dir, ...) + let dir_name = fnamemodify(a:dir, ':p') + if !isdirectory(dir_name) + call s:Tlist_Warning_Msg('Error: ' . dir_name . ' is not a directory') + return + endif + + if a:0 == 1 + " User specified file pattern + let pat = a:1 + else + " Default file pattern + let pat = '*' + endif + + echon "\r " + echon "\rProcessing files in directory " . fnamemodify(dir_name, ':p') + + call s:Tlist_Process_Dir(dir_name, pat) + + " Clear the displayed informational messages + echon "\r " +endfunction + " Tlist_Add_Files " Add the specified list of files to the taglist function! s:Tlist_Add_Files(...) @@ -2088,41 +2514,32 @@ function! s:Tlist_Add_Files(...) return endif - let flist = flist . "\n" - " Enable lazy screen updates let old_lazyredraw = &lazyredraw set lazyredraw - " Ignore the filetype autocommands - let old_eventignore = &eventignore - set eventignore=FileType - - " Save the 'filetype', as this will be changed temporarily - let old_filetype = &filetype - " Process one file at a time while flist != '' let one_file = strpart(flist, 0, stridx(flist, "\n")) let flist = strpart(flist, stridx(flist, "\n") + 1) - " Run the filetypedetect group of autocommands to determine - " the filetype for one_file - exe 'doautocmd filetypedetect BufRead ' . one_file + if one_file == '' + continue + endif + + let ftype = s:Tlist_Get_Filetype(one_file) echon "\r " echon "\rProcessing tags for " . fnamemodify(one_file, ':p:t') - silent call Tlist_Update_File_Tags(one_file, &filetype) + silent call Tlist_Update_File(one_file, ftype) endwhile " Clear the displayed informational messages echon "\r " " Restore the previous state - let &filetype = old_filetype - let &eventignore = old_eventignore let &lazyredraw = old_lazyredraw endfunction @@ -2204,6 +2621,11 @@ function! s:Tlist_Refresh() if s:Tlist_User_Removed_File(filename) return endif + + " If the taglist should not be auto updated, then return + if !g:Tlist_Auto_Update + return + endif endif let cur_lnum = line('.') @@ -2218,7 +2640,7 @@ function! s:Tlist_Refresh() let s:tlist_{fidx}_valid = 0 " Update the taglist and the window - call Tlist_Update_File_Tags(filename, ftype) + call Tlist_Update_File(filename, ftype) " Store the new file modification time let s:tlist_{fidx}_mtime = mtime @@ -2227,38 +2649,42 @@ function! s:Tlist_Refresh() " Update the taglist window if tlist_win != -1 - if g:Tlist_Show_One_File && s:tlist_cur_file_idx != fidx - " If displaying tags for only one file in the taglist - " window and about to display the tags for a new file, - " then center the current tag line for the new file - let center_tag_line = 1 - else - let center_tag_line = 0 - endif - " Disable screen updates let old_lazyredraw = &lazyredraw set nolazyredraw " Save the current window number - let cur_winnr = winnr() + let save_winnr = winnr() " Goto the taglist window - call s:Tlist_Open_Window() + call s:Tlist_Goto_Window() - if !g:Tlist_Auto_Highlight_Tag + if !g:Tlist_Auto_Highlight_Tag || !g:Tlist_Highlight_Tag_On_BufEnter " Save the cursor position let save_line = line('.') let save_col = col('.') endif " Update the taglist window - call s:Tlist_Explore_File(filename, ftype) + call s:Tlist_Window_Refresh_File(filename, ftype) - " Highlight the current tag - call s:Tlist_Highlight_Tag(filename, cur_lnum, 1, center_tag_line) + " Open the fold for the file + exe "silent! " . s:tlist_{fidx}_start . "," . + \ s:tlist_{fidx}_end . "foldopen!" - if !g:Tlist_Auto_Highlight_Tag + if g:Tlist_Highlight_Tag_On_BufEnter && g:Tlist_Auto_Highlight_Tag + if g:Tlist_Show_One_File && s:tlist_cur_file_idx != fidx + " If displaying tags for only one file in the taglist + " window and about to display the tags for a new file, + " then center the current tag line for the new file + let center_tag_line = 1 + else + let center_tag_line = 0 + endif + + " Highlight the current tag + call s:Tlist_Highlight_Tag(filename, cur_lnum, 1, center_tag_line) + else " Restore the cursor position if v:version >= 601 call cursor(save_line, save_col) @@ -2268,9 +2694,9 @@ function! s:Tlist_Refresh() endif endif - if s:tlist_app_name != "winmanager" - " Jump back to the original window - exe cur_winnr . 'wincmd w' + " Jump back to the original window + if save_winnr != winnr() + call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w') endif " Restore screen updates @@ -2327,7 +2753,7 @@ function! s:Tlist_Change_Sort(caller, action, sort_type) " Save the current line for later restoration let curline = '\V\^' . getline('.') . '\$' - call s:Tlist_Explore_File(s:tlist_{fidx}_filename, + call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename, \ s:tlist_{fidx}_filetype) " Go back to the cursor line before the tag list is sorted @@ -2341,14 +2767,14 @@ function! s:Tlist_Change_Sort(caller, action, sort_type) endif endfunction -" Tlist_Update_Tags() +" Tlist_Update_Current_File() " Update taglist for the current buffer by regenerating the tag list " Contributed by WEN Guopeng. -function! s:Tlist_Update_Tags() - call s:Tlist_Log_Msg('Tlist_Update_Tags()') +function! s:Tlist_Update_Current_File() + call s:Tlist_Log_Msg('Tlist_Update_Current_File()') if winnr() == bufwinnr(g:TagList_title) " In the taglist window. Update the current file - call s:Tlist_Update_Window() + call s:Tlist_Window_Update_File() else " Not in the taglist window. Update the current buffer let filename = fnamemodify(bufname('%'), ':p') @@ -2356,14 +2782,14 @@ function! s:Tlist_Update_Tags() if fidx != -1 let s:tlist_{fidx}_valid = 0 endif - call Tlist_Update_File_Tags(filename, &filetype) + call Tlist_Update_File(filename, &filetype) endif endfunction -" Tlist_Update_Window() -" Update the window by regenerating the tag list -function! s:Tlist_Update_Window() - call s:Tlist_Log_Msg('Tlist_Update_Window()') +" Tlist_Window_Update_File() +" Update the tags displayed in the taglist window +function! s:Tlist_Window_Update_File() + call s:Tlist_Log_Msg('Tlist_Window_Update_File()') let fidx = s:Tlist_Get_File_Index_By_Linenum(line('.')) if fidx == -1 return @@ -2378,15 +2804,16 @@ function! s:Tlist_Update_Window() let s:tlist_{fidx}_valid = 0 " Update the taglist window - call s:Tlist_Explore_File(s:tlist_{fidx}_filename, s:tlist_{fidx}_filetype) + call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename, + \ s:tlist_{fidx}_filetype) " Go back to the tag line before the list is updated call search(curline, 'w') endfunction -" Tlist_Get_Tag_Index() -" Return the tag index for the specified line -function! s:Tlist_Get_Tag_Index(fidx, lnum) +" Tlist_Get_Tag_Type_By_Linenum() +" Return the tag type index for the specified line in the taglist window +function! s:Tlist_Get_Tag_Type_By_Linenum(fidx, lnum) let ftype = s:tlist_{a:fidx}_filetype " Determine to which tag type the current line number belongs to using the @@ -2394,7 +2821,8 @@ function! s:Tlist_Get_Tag_Index(fidx, lnum) let i = 1 while i <= s:tlist_{ftype}_count let ttype = s:tlist_{ftype}_{i}_name - let start_lnum = s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_start + let start_lnum = + \ s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset let end = start_lnum + s:tlist_{a:fidx}_{ttype}_count if a:lnum >= start_lnum && a:lnum <= end break @@ -2404,11 +2832,25 @@ function! s:Tlist_Get_Tag_Index(fidx, lnum) " Current line doesn't belong to any of the displayed tag types if i > s:tlist_{ftype}_count + return '' + endif + + return ttype +endfunction + +" Tlist_Get_Tag_Index() +" Return the tag index for the specified line +function! s:Tlist_Get_Tag_Index(fidx, lnum) + let ttype = s:Tlist_Get_Tag_Type_By_Linenum(a:fidx, a:lnum) + + " Current line doesn't belong to any of the displayed tag types + if ttype == '' return 0 endif " Compute the index into the displayed tags for the tag type - let tidx = a:lnum - start_lnum + let ttype_lnum = s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset + let tidx = a:lnum - ttype_lnum if tidx == 0 return 0 endif @@ -2417,18 +2859,158 @@ function! s:Tlist_Get_Tag_Index(fidx, lnum) return s:tlist_{a:fidx}_{ttype}_{tidx} endfunction -" Tlist_Highlight_Tagline -" Higlight the current tagline -function! s:Tlist_Highlight_Tagline() +" Tlist_Window_Highlight_Line +" Highlight the current line +function! s:Tlist_Window_Highlight_Line() " Clear previously selected name match none - " Highlight the current selected name + " Highlight the current line if g:Tlist_Display_Prototype == 0 - exe 'match TagListTagName /\%' . line('.') . 'l\s\+\zs.*/' + let pat = '/\%' . line('.') . 'l\s\+\zs.*/' else - exe 'match TagListTagName /\%' . line('.') . 'l.*/' + let pat = '/\%' . line('.') . 'l.*/' endif + + exe 'match TagListTagName ' . pat +endfunction + +" Tlist_Open_File +" Open the specified file in either a new window or an existing window +" and place the cursor at the specified tag pattern +function! s:Tlist_Open_File(win_ctrl, filename, tagpat) + call s:Tlist_Log_Msg('Tlist_Open_File (' . a:filename . ')') + let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh + let s:Tlist_Skip_Refresh = 1 + + if s:tlist_app_name == "winmanager" + " Let the winmanager edit the file + call WinManagerFileEdit(a:filename, a:win_ctrl) + else + + " Goto the window containing the file. If the window is not there, open a + " new window + let winnum = bufwinnr(a:filename) + if winnum == -1 + " Locate the previously used window for opening a file + let fwin_num = 0 + let first_usable_win = 0 + + let i = 1 + let bnum = winbufnr(i) + while bnum != -1 + if getwinvar(i, 'tlist_file_window') == 'yes' + let fwin_num = i + break + endif + if first_usable_win == 0 && bufname(bnum) != g:TagList_title && + \ getbufvar(bnum, '&buftype') == '' + " First non-taglist and a non-plugin window + let first_usable_win = i + endif + let i = i + 1 + let bnum = winbufnr(i) + endwhile + + " If a previously used window is not found, then use the first + " non-taglist window + if fwin_num == 0 + let fwin_num = first_usable_win + endif + + if fwin_num != 0 + " Jump to the file window + exe fwin_num . "wincmd w" + + " If the user asked to jump to the tag in a new window, then split + " the existing window into two. + if a:win_ctrl == 1 + split + endif + exe "edit " . escape(a:filename, ' ') + else + " Open a new window + if g:Tlist_Use_Horiz_Window + exe 'leftabove split ' . escape(a:filename, ' ') + else + if winbufnr(2) == -1 + " Only the taglist window is present + if g:Tlist_Use_Right_Window + exe 'leftabove vertical split ' . + \ escape(a:filename, ' ') + else + exe 'rightbelow vertical split ' . + \ escape(a:filename, ' ') + endif + + " Go to the taglist window to change the window size to + " the user configured value + call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') + if g:Tlist_Use_Horiz_Window + exe 'resize ' . g:Tlist_WinHeight + else + exe 'vertical resize ' . g:Tlist_WinWidth + endif + " Go back to the file window + call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') + else + " A plugin or help window is also present + wincmd w + exe 'leftabove split ' . escape(a:filename, ' ') + endif + endif + endif + " Mark the window, so that it can be reused. + let w:tlist_file_window = "yes" + else + exe winnum . 'wincmd w' + + " If the user asked to jump to the tag in a new window, then split the + " existing window into two. + if a:win_ctrl == 1 + split + endif + endif + endif + + " Jump to the tag + if a:tagpat != '' + " Add the current cursor position to the jump list, so that user can + " jump back using the ' and ` marks. + mark ' + silent call search(a:tagpat, 'w') + + " Bring the line to the middle of the window + normal! z. + + " If the line is inside a fold, open the fold + if foldclosed('.') != -1 + .foldopen + endif + endif + + " If the user selects to preview the tag then jump back to the + " taglist window + if a:win_ctrl == 2 + " Go back to the taglist window + let winnum = bufwinnr(g:TagList_title) + exe winnum . 'wincmd w' + else + " If the user has selected to close the taglist window, when a + " tag is selected, close the taglist window + if g:Tlist_Close_On_Select + call s:Tlist_Goto_Window() + close + + " Go back to the window displaying the selected file + let wnum = bufwinnr(a:filename) + if wnum != -1 && wnum != winnr() + call s:Tlist_Exe_Cmd_No_Acmds(wnum . 'wincmd w') + endif + endif + endif + + let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh endfunction " Tlist_Jump_To_Tag() @@ -2466,7 +3048,7 @@ function! s:Tlist_Jump_To_Tag(win_ctrl) let tagpat = s:Tlist_Get_Tag_SearchPat(fidx, tidx) " Highlight the tagline - call s:Tlist_Highlight_Tagline() + call s:Tlist_Window_Highlight_Line() else " Selected a line which is not a tag name. Just edit the file let tagpat = '' @@ -2475,126 +3057,10 @@ function! s:Tlist_Jump_To_Tag(win_ctrl) call s:Tlist_Open_File(a:win_ctrl, s:tlist_{fidx}_filename, tagpat) endfunction -" Tlist_Open_File -" Open the specified file in either a new window or an existing window -" and place the cursor at the specified tag pattern -function! s:Tlist_Open_File(win_ctrl, filename, tagpat) - call s:Tlist_Log_Msg('Tlist_Open_File (' . a:filename . ')') - let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh - let s:Tlist_Skip_Refresh = 1 - - if s:tlist_app_name == "winmanager" - " Let the winmanager edit the file - call WinManagerFileEdit(a:filename, a:win_ctrl) - else - " Goto the window containing the file. If the window is not there, open a - " new window - let winnum = bufwinnr(a:filename) - if winnum == -1 - " Locate the previously used window for opening a file - let fwin_num = 0 - let first_usable_win = 0 - - let i = 1 - while winbufnr(i) != -1 - if getwinvar(i, 'tlist_file_window') == 'yes' - let fwin_num = i - break - endif - if first_usable_win == 0 && bufname(winbufnr(i)) != g:TagList_title - " First non-taglist window - let first_usable_win = i - endif - let i = i + 1 - endwhile - - " If a previously used window is not found, then use the first - " non-taglist window - if fwin_num == 0 - let fwin_num = first_usable_win - endif - - if fwin_num != 0 - " Jump to the file window - exe fwin_num . "wincmd w" - - " If the user asked to jump to the tag in a new window, then split - " the existing window into two. - if a:win_ctrl == 1 - split - endif - exe "edit " . a:filename - else - " Open a new window - if g:Tlist_Use_Horiz_Window - exe 'leftabove split #' . bufnr(a:filename) - " Go to the taglist window to change the window size to the user - " configured value - wincmd p - exe 'resize ' . g:Tlist_WinHeight - " Go back to the file window - wincmd p - else - " Open the file in a window and skip refreshing the taglist - " window - exe 'rightbelow vertical split #' . bufnr(a:filename) - " Go to the taglist window to change the window size to the user - " configured value - wincmd p - exe 'vertical resize ' . g:Tlist_WinWidth - " Go back to the file window - wincmd p - endif - endif - " Mark the window, so that it can be reused. - let w:tlist_file_window = "yes" - else - exe winnum . 'wincmd w' - - " If the user asked to jump to the tag in a new window, then split the - " existing window into two. - if a:win_ctrl == 1 - split - endif - endif - endif - - " Jump to the tag - if a:tagpat != '' - " Add the current cursor position to the jump list, so that user can - " jump back using the ' and ` marks. - mark ' - silent call search(a:tagpat, 'w') - endif - - " Bring the line to the middle of the window - normal! z. - - " If the line is inside a fold, open the fold - if foldclosed('.') != -1 - .foldopen - endif - - " If the user selects to preview the tag then jump back to the - " taglist window - if a:win_ctrl == 2 - " Go back to the taglist window - let winnum = bufwinnr(g:TagList_title) - exe winnum . 'wincmd w' - endif - - let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh -endfunction - -" Tlist_Show_Tag_Prototype() -" Display the prototype of the tag under the cursor -function! s:Tlist_Show_Tag_Prototype() - call s:Tlist_Log_Msg('Tlist_Show_Tag_Prototype()') - " If we already display prototype in the tag window, no need to - " display it in the status line - if g:Tlist_Display_Prototype - return - endif +" Tlist_Show_Info() +" Display information about the entry under the cursor +function! s:Tlist_Show_Info() + call s:Tlist_Log_Msg('Tlist_Show_Info()') " Clear the previously displayed line echo @@ -2618,9 +3084,40 @@ function! s:Tlist_Show_Tag_Prototype() return endif + if lnum == s:tlist_{fidx}_start + " Cursor is on a file name + let fname = s:tlist_{fidx}_filename + if strlen(fname) > 50 + let fname = fnamemodify(fname, ':t') + endif + echo fname . ', Filetype=' . s:tlist_{fidx}_filetype . + \ ', Tag count=' . s:tlist_{fidx}_tag_count + return + endif + " Get the tag output line for the current tag let tidx = s:Tlist_Get_Tag_Index(fidx, lnum) if tidx == 0 + " Cursor is on a tag type + let ttype = s:Tlist_Get_Tag_Type_By_Linenum(fidx, lnum) + if ttype == '' + return + endif + + let ttype_name = '' + + let ftype = s:tlist_{fidx}_filetype + let i = 1 + while i <= s:tlist_{ftype}_count + if ttype == s:tlist_{ftype}_{i}_name + let ttype_name = s:tlist_{ftype}_{i}_fullname + break + endif + let i = i + 1 + endwhile + + echo 'Tag type=' . ttype_name . + \ ', Tag count=' . s:tlist_{fidx}_{ttype}_count return endif @@ -2699,7 +3196,7 @@ endfunction " Tlist_Highlight_Tag() " Highlight the current tag " cntx == 1, Called by the taglist plugin itself -" cntx == 2, Forced by the user through the TlistSync command +" cntx == 2, Forced by the user through the TlistHighlightTag command " center = 1, move the tag line to the center of the taglist window function! s:Tlist_Highlight_Tag(filename, cur_lnum, cntx, center) " Highlight the current tag only if the user configured the @@ -2725,15 +3222,16 @@ function! s:Tlist_Highlight_Tag(filename, cur_lnum, cntx, center) return endif + " If the file is currently not displayed in the taglist window, then retrn + if !s:tlist_{fidx}_visible + return + endif + " If there are no tags for this file, then no need to proceed further if s:tlist_{fidx}_tag_count == 0 return endif - " If part of winmanager then disable winmanager autocommands - if s:tlist_app_name == "winmanager" - call WinManagerSuspendAUs() - endif " Ignore all autocommands let old_ei = &eventignore set eventignore=all @@ -2774,13 +3272,7 @@ function! s:Tlist_Highlight_Tag(filename, cur_lnum, cntx, center) call winline() if !in_taglist_window - let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh - let s:Tlist_Skip_Refresh = 1 exe org_winnr . 'wincmd w' - let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh - endif - if s:tlist_app_name == "winmanager" - call WinManagerResumeAUs() endif " Restore the autocommands @@ -2789,11 +3281,11 @@ function! s:Tlist_Highlight_Tag(filename, cur_lnum, cntx, center) endif " Extract the tag type - let ttype = s:Tlist_Get_Tag_Type(fidx, tidx) + let ttype = s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx) " Compute the line number " Start of file + Start of tag type + offset - let lnum = s:tlist_{fidx}_start + s:tlist_{fidx}_{ttype}_start + + let lnum = s:tlist_{fidx}_start + s:tlist_{fidx}_{ttype}_offset + \ s:tlist_{fidx}_{tidx}_ttype_idx " Goto the line containing the tag @@ -2815,18 +3307,11 @@ function! s:Tlist_Highlight_Tag(filename, cur_lnum, cntx, center) endif " Highlight the tag name - call s:Tlist_Highlight_Tagline() + call s:Tlist_Window_Highlight_Line() " Go back to the original window if !in_taglist_window - let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh - let s:Tlist_Skip_Refresh = 1 exe org_winnr . 'wincmd w' - let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh - endif - - if s:tlist_app_name == "winmanager" - call WinManagerResumeAUs() endif " Restore the autocommands @@ -3013,9 +3498,6 @@ function! s:Tlist_Session_Load(...) let w:tlist_file_window = "yes" endif - " Open the taglist window - call s:Tlist_Open_Window() - " Source the session file exe 'source ' . sessionfile @@ -3085,7 +3567,7 @@ function! s:Tlist_Session_Load(...) if exists('g:tlist_' . i . '_' . ttype) let s:tlist_{fidx}_{ttype} = g:tlist_{i}_{ttype} unlet! g:tlist_{i}_{ttype} - let s:tlist_{fidx}_{ttype}_start = 0 + let s:tlist_{fidx}_{ttype}_offset = 0 let s:tlist_{fidx}_{ttype}_count = g:tlist_{i}_{ttype}_count unlet! g:tlist_{i}_{ttype}_count @@ -3097,7 +3579,7 @@ function! s:Tlist_Session_Load(...) endwhile else let s:tlist_{fidx}_{ttype} = '' - let s:tlist_{fidx}_{ttype}_start = 0 + let s:tlist_{fidx}_{ttype}_offset = 0 let s:tlist_{fidx}_{ttype}_count = 0 endif @@ -3107,17 +3589,22 @@ function! s:Tlist_Session_Load(...) let i = i + 1 endwhile - " Initialize the taglist window - call s:Tlist_Refresh_Window() + " If the taglist window is open, then update it + let winnum = bufwinnr(g:TagList_title) + if winnum != -1 + let save_winnr = winnr() - " Go back to the original window - let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh - let s:Tlist_Skip_Refresh = 1 - wincmd p - let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh + " Goto the taglist window + call s:Tlist_Goto_Window() - " Highlight the current tag - call s:Tlist_Highlight_Tag(fnamemodify(bufname('%'), ':p'), line('.'), 1, 1) + " Refresh the taglist window + call s:Tlist_Window_Refresh() + + " Go back to the original window + if save_winnr != winnr() + call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') + endif + endif endfunction " Tlist_Session_Save @@ -3210,13 +3697,35 @@ function! s:Tlist_Session_Save(...) let &verbose = old_verbose endfunction -" Tlist_Update_File_Display -" Update a file displayed in the taglist window. -" action == 1, Close the fold for the file -" action == 2, Remove the file from the taglist window -function! s:Tlist_Update_File_Display(filename, action) - call s:Tlist_Log_Msg('Tlist_Update_File_Display (' . a:filename . - \ ', action = ' . a:action . ')') +" Tlist_Buffer_Removed +" A buffer is wiped out from the Vim buffer list. Remove the tags defined +" for that file +function! s:Tlist_Buffer_Removed(filename) + call s:Tlist_Log_Msg('Tlist_Buffer_Removed (' . a:filename . ')') + + " Make sure a valid filename is supplied + if a:filename == '' + return + endif + + " Get tag list index of the specified file + let fidx = s:Tlist_Get_File_Index(a:filename) + if fidx == -1 + " File not present in the taglist + return + endif + + " Remove the file from the list + call s:Tlist_Remove_File(fidx, 0) +endfunction + +" When a buffer is deleted, remove the file from the taglist +autocmd BufDelete * silent call s:Tlist_Buffer_Removed(expand(':p')) + +" Tlist_Close_File_Fold +" Close the fold for the specified file +function! s:Tlist_Close_File_Fold(filename) + call s:Tlist_Log_Msg('Tlist_Close_File_Fold (' . a:filename . ')') " Make sure a valid filename is supplied if a:filename == '' return @@ -3246,31 +3755,23 @@ function! s:Tlist_Update_File_Display(filename, action) " Go to the taglist window if !in_taglist_window - exe winnum . 'wincmd w' + call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w') endif " Save the cursor position let save_lnum = line('.') " Perform the requested action on the file - if a:action == 1 && g:Tlist_File_Fold_Auto_Close - " Close the fold for the file - exe "silent! " . s:tlist_{fidx}_start . "," . - \ s:tlist_{fidx}_end . "foldclose" - elseif a:action == 2 - " Remove the file from the list - call s:Tlist_Remove_File(fidx, 0) - endif + " Close the fold for the file + exe "silent! " . s:tlist_{fidx}_start . "," . + \ s:tlist_{fidx}_end . "foldclose" " Move the cursor to the original location exe save_lnum " Go back to the original window if !in_taglist_window - let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh - let s:Tlist_Skip_Refresh = 1 - exe org_winnr . 'wincmd w' - let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh + call s:Tlist_Exe_Cmd_No_Acmds(org_winnr . 'wincmd w') endif endfunction @@ -3278,7 +3779,7 @@ endfunction " Open the taglist window automatically on Vim startup. " Open the window only when files present in any of the Vim windows support " tags. -function! s:Tlist_Check_Auto_Open () +function! s:Tlist_Check_Auto_Open() let open = 0 let i = 1 @@ -3294,56 +3795,29 @@ function! s:Tlist_Check_Auto_Open () endwhile if open - call s:Tlist_Toggle_Window() + call s:Tlist_Window_Toggle() endif endfunction -" Define the taglist autocommand to automatically open the taglist window on -" Vim startup -if g:Tlist_Auto_Open - autocmd VimEnter * nested call s:Tlist_Check_Auto_Open() -endif - -" Refresh the taglist -if g:Tlist_Process_File_Always - autocmd BufEnter * call s:Tlist_Refresh() -endif - -" Define the user commands to manage the taglist window -command! -nargs=0 Tlist call s:Tlist_Toggle_Window() -command! -nargs=+ -complete=file TlistAddFiles call s:Tlist_Add_Files() -command! -nargs=0 TlistClose call s:Tlist_Close_Window() -command! -nargs=0 TlistUpdate call s:Tlist_Update_Tags() -command! -nargs=0 TlistSync call s:Tlist_Highlight_Tag( - \ fnamemodify(bufname('%'), ':p'), line('.'), 2, 1) -command! -nargs=* -complete=buffer TlistShowPrototype - \ echo Tlist_Get_Tag_Prototype_By_Line() -command! -nargs=* -complete=buffer TlistShowTag - \ echo Tlist_Get_Tagname_By_Line() -command! -nargs=* -complete=file TlistSessionLoad - \ call s:Tlist_Session_Load() -command! -nargs=* -complete=file TlistSessionSave - \ call s:Tlist_Session_Save() - function! s:Tlist_Add_Base_Menu() call s:Tlist_Log_Msg('Adding the base menu') " Add the menu - amenu T&ags.Refresh\ menu :call Tlist_Menu_Refresh() - amenu T&ags.Sort\ menu\ by.Name + anoremenu T&ags.Refresh\ menu :call Tlist_Menu_Refresh() + anoremenu T&ags.Sort\ menu\ by.Name \ :call Tlist_Change_Sort(2, 2, 'name') - amenu T&ags.Sort\ menu\ by.Order + anoremenu T&ags.Sort\ menu\ by.Order \ :call Tlist_Change_Sort(2, 2, 'order') - amenu T&ags.-SEP1- : + anoremenu T&ags.-SEP1- : if &mousemodel =~ 'popup' - amenu PopUp.T&ags.Refresh\ menu + anoremenu PopUp.T&ags.Refresh\ menu \ :call Tlist_Menu_Refresh() - amenu PopUp.T&ags.Sort\ menu\ by.Name + anoremenu PopUp.T&ags.Sort\ menu\ by.Name \ :call Tlist_Change_Sort(2, 2, 'name') - amenu PopUp.T&ags.Sort\ menu\ by.Order + anoremenu PopUp.T&ags.Sort\ menu\ by.Order \ :call Tlist_Change_Sort(2, 2, 'order') - amenu PopUp.T&ags.-SEP1- : + anoremenu PopUp.T&ags.-SEP1- : endif endfunction @@ -3558,7 +4032,8 @@ function! s:Tlist_Menu_Remove_File() silent! unmenu PopUp.T&ags endif - call s:Tlist_Add_Base_Menu() + " Add a dummy menu item to retain teared off menu + noremenu T&ags.Dummy l silent! unmenu! T&ags if &mousemodel =~ 'popup' @@ -3567,6 +4042,9 @@ function! s:Tlist_Menu_Remove_File() call s:Tlist_Add_Base_Menu() + " Remove the dummy menu item + unmenu T&ags.Dummy + let s:tlist_menu_empty = 1 endfunction @@ -3581,7 +4059,7 @@ function! s:Tlist_Menu_Refresh() endif " Update the taglist, menu and window - call s:Tlist_Update_Tags() + call s:Tlist_Update_Current_File() endfunction " Tlist_Menu_Jump_To_Tag @@ -3630,9 +4108,18 @@ function! s:Tlist_Menu_Init() call s:Tlist_Menu_Update_File(0) endfunction -if g:Tlist_Show_Menu - autocmd GUIEnter * call s:Tlist_Menu_Init() -endif +" Tlist_Vim_Session_Load +" Initialize the taglist window/buffer, which is created when loading +" a Vim session file. +function! s:Tlist_Vim_Session_Load() + call s:Tlist_Log_Msg('Tlist_Vim_Session_Load') + + " Initialize the taglist window + call s:Tlist_Window_Init() + + " Refresh the taglist window + call s:Tlist_Window_Refresh() +endfunction " Tlist_Set_App " Set the name of the external plugin/application to which taglist @@ -3666,15 +4153,15 @@ function! TagList_Start() " Initialize the taglist window, if it is not already initialized if !exists('s:tlist_window_initialized') || !s:tlist_window_initialized - call s:Tlist_Init_Window() - call s:Tlist_Refresh_Window() + call s:Tlist_Window_Init() + call s:Tlist_Window_Refresh() let s:tlist_window_initialized = 1 endif " Update the taglist window if bufnum != -1 - if !s:Tlist_Skip_File(filename, ftype) - call s:Tlist_Explore_File(filename, ftype) + if !s:Tlist_Skip_File(filename, ftype) && g:Tlist_Auto_Update + call s:Tlist_Window_Refresh_File(filename, ftype) endif endif endfunction