posts - 403, comments - 310, trackbacks - 0, articles - 7
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

[zz]vim+ctags+taglist插件安装使用

Posted on 2007-06-12 11:38 ZelluX 阅读(18302) 评论(0)  编辑  收藏 所属分类: Linux
For using taglist plugin,you must install ctags plugin first.
1.ctags
(1)到http://ctags.sourceforge.net/下载ctags源码ctags-5.6.tar.gz
http://prdownloads.sourceforge.net/ctags/ctags-5.6.tar.gz

windows user need to set a variable in "_vimrc" file lied in you $vim home directory.

let Tlist_Ctags_Cmd='c:\xxx\Ctags56'


linux user can use configure && make && make install to install it.

(2)使用
[/home/brimmer/src]$ ctags -R
"-R"表示递归创建,也就包括源代码根目录下的所有子目录下的源程序。"tags"文件中包括这些对象的列表:
l 用#define定义的宏
l 枚举型变量的值
l 函数的定义、原型和声明
l 名字空间(namespace)
l 类型定义(typedefs)
l 变量(包括定义和声明)
l 类(class)、结构(struct)、枚举类型(enum)和联合(union)
l 类、结构和联合中成员变量或函数
VIM用这个"tags"文件来定位上面这些做了标记的对象,下面介绍一下定位这些对象的方法:

1) 用命令行。在运行vim的时候加上"-t"参数,例如:
[/home/brimmer/src]$ vim -t foo_bar
这个命令将打开定义"foo_bar"(变量或函数或其它)的文件,并把光标定位到这一行。
2) 在vim编辑器内用":ta"命令,例如:
:ta foo_bar
3) 最方便的方法是把光标移到变量名或函数名上,然后按下"Ctrl-]"。用"Ctrl-o"退回原来的地方。
注意:运行vim的时候,必须在"tags"文件所在的目录下运行。否则,运行vim的时候还要用":set tags="命令设定"tags"文件的路径,这样vim才能找到"tags"文件。

在函数中移动光标
[{ 转到上一个位于第一列的"{"
}] 转到下一个位于第一列的"{"
{ 转到上一个空行
} 转到下一个空行 ([ and ] 也分别是两个指令)
gd 转到当前光标所指的局部变量的定义
* 转到当前光标所指的单词下一次出现的地方
# 转到当前光标所指的单词上一次出现的地方
Vim 的创造者是一名计算机程序员,因此这就不奇怪 Vim 中有许多帮助编写程序的功能:
跳转到标识符被定义和使用的地方;在另一个窗口中预览有关的声明等等。
(ctags使用部分参考了 文章“ctags和vim”,原文在
http://hi.baidu.com/original/blog/item/2cf8d53f00b7fcc27d1e71f0.html
更多使用也请参考原文)


2. taglist
能够列出源文件中的tag(function, class, variable, etc)并跳转.
注意:taglist依赖于ctags,所以要先装ctags,否则taglist装了也没法用!
(1)到http://vim.sourceforge.net/scripts/script.php?script_id=273
下载taglist_42.zip,即
http://vim.sourceforge.net/scripts/download_script.php?src_id=6416
(2)解压得到两个文件
# unzip -d taglist taglist_42.zip
# cd taglist
# tree
.
|-- doc
| `-- taglist.txt
`-- plugin
`-- taglist.vim
(3)安装
cp doc/taglist.txt /usr/share/vim/vim61/doc/
cp plugin/taglist.vim /usr/share/vim/vim61/plugin/
(4)配置和使用
cd /usr/share/vim/vim61/doc/
启动vim,用 “:helptags .”来配置好帮助文件
重启vim,用“:TlistToggle”来打开和关闭taglist窗口。
可以用“:help taglist”来获得更多帮助信

---------------------下面是一篇英文的taglist配置大全-------------------------
" File: taglist.vim
" Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
" Version: 3.1
" Last Modified: Nov 12003
"
" The "Tag List" plugin is a source code browser plugin for Vim and
" provides an overview of the structure of source code files and allows
" you to efficiently browse through source code files for different
" programming languages.  You can visit the taglist plugin home page for
" more information:
"
"       http://www.geocities.com/yegappan/taglist
"
" You can subscribe to the taglist mailing list to post your questions
" or suggestions for improvement or to report bugs. Visit the following
" page for subscribing to the mailing list:
"
"       http://groups.yahoo.com/group/taglist/
"
" For more information about using this plugin, after installing the
" taglist plugin, use the ":help taglist" command.
"
" Installation
" ------------
" 1. Download the taglist.zip file and unzip the files to the $HOME/.vim
"    or the $HOME/vimfiles or the $VIM/vimfiles directory. This should
"    unzip the following two files (the directory structure should be
"    preserved):
"
"       plugin/taglist.vim - main taglist plugin file
"       doc/taglist.txt    - documentation (help) file
"
"    Refer to the 'add-plugin', 'add-global-plugin' and 'runtimepath'
"    Vim help pages for more details about installing Vim plugins.
" 2. Change to the $HOME/.vim/doc or $HOME/vimfiles/doc or
"    $VIM/doc/vimfiles directory, start Vim and run the ":helptags ."
"    command to process the taglist help file.
" 3. Set the Tlist_Ctags_Cmd variable to point to the location of the
"    exuberant ctags utility (not to the directory) in the .vimrc file.
" 4. If you are running a terminal/console version of Vim and the
"    terminal doesn't support changing the window width then set the
"    'Tlist_Inc_Winwidth' variable to 0 in the .vimrc file.
" 5. Restart Vim.
" 6. You can now use the ":Tlist" 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') || &cp
    finish
endif
let loaded_taglist
=1

" Location of the exuberant ctags tool
if !exists('Tlist_Ctags_Cmd')
    let Tlist_Ctags_Cmd = 'ctags'
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

" 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

"------------------- end of user configurable options --------------------

" Initialize the taglist plugin local variables for the supported file types
" and tag types

" assembly language
let s:tlist_def_asm_settings 
= 'asm;d:define;l:label;m:macro;t:type'

" aspperl language
let s:tlist_def_aspperl_settings = 'asp;f:function;s:sub;v:variable'

" aspvbs language
let s:tlist_def_aspvbs_settings 
= 'asp;f:function;s:sub;v:variable'

" awk language
let s:tlist_def_awk_settings = 'awk;f:function'

" beta language
let s:tlist_def_beta_settings 
= 'beta;f:fragment;s:pattern;v:virtual'

" c language
let s:tlist_def_c_settings = 'c;d:macro;g:enum;s:struct;u:union;t:typedef;' .
                           \ 'v:variable;f:function'

" c++ language
let s:tlist_def_cpp_settings 
= 'c++;v:variable;d:macro;t:typedef;c:class;' .
                             \ 'n:namespace;g:enum;s:struct;u:union;f:
function'

" c# language
let s:tlist_def_cs_settings = 'c#;d:macro;t:typedef;n:namespace;c:class;' .
                             \ 'E:event;g:enum;s:struct;i:interface;' .
                             \ 'p:properties;m:method'

" cobol language
let s:tlist_def_cobol_settings 
= 'cobol;d:data;f:file;g:group;p:paragraph;' .
                               \ 'P:program;s:section'

" eiffel language
let s:tlist_def_eiffel_settings = 'eiffel;c:class;f:feature'

" erlang language
let s:tlist_def_erlang_settings 
= 'erlang;d:macro;r:record;m:module;f:function'

" expect (same as tcl) language
let s:tlist_def_expect_settings = 'expect;c:class;f:method;p:procedure'

" fortran language
let s:tlist_def_fortran_settings 
= 'fortran;p:program;b:block data;' .
                    \ 'c:common;e:entry;i:interface;k:type;l:label;m:module;' .
                    \ 'n:namelist;t:derived;v:variable;f:
function;s:subroutine'

" HTML language
let s:tlist_def_html_settings = 'html;a:anchor;f:javascript function'

" java language
let s:tlist_def_java_settings 
= 'java;p:package;c:class;i:interface;' .
                              \ 'f:field;m:method'

" javascript language
let s:tlist_def_javascript_settings = 'javascript;f:function'

" lisp language
let s:tlist_def_lisp_settings 
= 'lisp;f:function'

" lua language
let s:tlist_def_lua_settings = 'lua;f:function'

" makefiles
let s:tlist_def_make_settings 
= 'make;m:macro'

" pascal language
let s:tlist_def_pascal_settings = 'pascal;f:function;p:procedure'

" perl language
let s:tlist_def_perl_settings 
= 'perl;p:package;s:subroutine'

" php language
let s:tlist_def_php_settings = 'php;c:class;f:function'

" python language
let s:tlist_def_python_settings 
= 'python;c:class;m:member;f:function'

" rexx language
let s:tlist_def_rexx_settings = 'rexx;s:subroutine'

" ruby language
let s:tlist_def_ruby_settings 
= 'ruby;c:class;f:method;F:function;' .
                              \ 'm:singleton method'

" scheme language
let s:tlist_def_scheme_settings = 'scheme;s:set;f:function'

" shell language
let s:tlist_def_sh_settings 
= 'sh;f:function'

" C shell language
let s:tlist_def_csh_settings = 'sh;f:function'

" Z shell language
let s:tlist_def_zsh_settings 
= 'sh;f:function'

" slang language
let s:tlist_def_slang_settings = 'slang;n:namespace;f:function'

" sml language
let s:tlist_def_sml_settings 
= 'sml;e:exception;c:functor;s:signature;' .
                             \ 'r:structure;t:type;v:value;f:
function'

" sql language
let s:tlist_def_sql_settings = 'sql;c:cursor;F:field;P:package;r:record;' .
            \ 's:subtype;t:table;T:trigger;v:variable;f:function;p:procedure'

" tcl language
let s:tlist_def_tcl_settings 
= 'tcl;c:class;f:method;p:procedure'

" vera language
let s:tlist_def_vera_settings = 'vera;c:class;d:macro;e:enumerator;' .
                                \ 'f:function;g:enum;m:member;p:program;' .
                                \ 'P:prototype;t:task;T:typedef;v:variable;' .
                                \ 'x:externvar'

"verilog language
let s:tlist_def_verilog_settings 
= 'verilog;m:module;P:parameter;r:register;' .
                                 \ 't:task;w:write;p:port;v:variable;f:
function'

" vim language
let s:tlist_def_vim_settings = 'vim;a:autocmds;v:variable;f:function'

" yacc language
let s:tlist_def_yacc_settings 
= 'yacc;l:label'

"------------------- end of language specific options --------------------

" Vim window size is changed or not
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
let s:tlist_file_count 
= 0
" Number of filetypes supported by taglist
let s:tlist_ftype_count = 0
" Current active file index
let s:tlist_cur_fidx 
= -1
" Is taglist part of the winmanager plugin
let s:tlist_part_of_winmanager = 0
" Are we displaying brief help text
let s:tlist_brief_help 
= 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
" file window from one of the taglist functions. The 'Tlist_Skip_Refresh'
" variable is used to skip the refresh of the taglist window and is set
" and cleared appropriately.
let s:Tlist_Skip_Refresh = 0

" Tlist_Display_Help()
function! s:Tlist_Display_Help()
    
if s:tlist_part_of_winmanager
        
" To handle a bug in the winmanager plugin, add a space at the
        
" last line
        call setline('$', ' ')
    endif

    
if s:tlist_brief_help
        
" Add the brief help
        call append(0, '
" Press ? to display help text')
    
else
        
" Add the extensive help
        call append(0, '
" <enter> : Jump to tag definition')
        call append(
1, '" o : Jump to tag definition in new window')
        call append(2, '
" p : Preview the tag definition')
        call append(
3, '" <space> : Display tag prototype')
        call append(4, '
" u : Update tag list')
        call append(
5, '" s : Select sort field')
        call append(6, '
" d : Remove file from taglist')
        call append(
7, '" x : Zoom-out/Zoom-in taglist window')
        call append(8, '
" + : Open a fold')
        call append(
9, '" - : Close a fold')
        call append(10, '
" * : Open all folds')
        call append(
11, '" = : Close all folds')
        call append(12, '
" q : Close the taglist window')
        call append(
13, '" ? : Remove help text')
    endif
endfunction

" Tlist_Toggle_Help_Text()
" Toggle taglist plugin help text between the full version and the brief
" version
function! s:Tlist_Toggle_Help_Text()
    
if g:Tlist_Compact_Format
        
" In compact display mode, do not display help
        return
    endif

    
" Include the empty line displayed after the help text
    let brief_help_size 
= 1
    let full_help_size 
= 14

    setlocal modifiable

    
" Set report option to a huge value to prevent informational messages
    
" while deleting the lines
    let old_report 
= &report
    set report
=99999

    
" Remove the currently highlighted tag. Otherwise, the help text
    
" might be highlighted by mistake
    match none

    
" Toggle between brief and full help text
    if s:tlist_brief_help
        let s:tlist_brief_help = 0

        
" Remove the previous help
        exe '
1,' . brief_help_size . ' delete _'

        
" Adjust the start/end line numbers for the files
        call s:Tlist_Update_Line_Offsets(0, 1, full_help_size - brief_help_size)
    else
        let s:tlist_brief_help = 1

        
" Remove the previous help
        exe '
1,' . full_help_size . ' delete _'

        
" Adjust the start/end line numbers for the files
        call s:Tlist_Update_Line_Offsets(0, 0, full_help_size - brief_help_size)
    endif

    call s:Tlist_Display_Help()

    
" Restore the report option
    let 
&report = old_report

    setlocal nomodifiable
endfunction

" Tlist_Warning_Msg()
" Display a message using WarningMsg highlight group
function! s:Tlist_Warning_Msg(msg)
    echohl WarningMsg
    echomsg a:msg
    echohl None
endfunction

" Tlist_Get_File_Index()
" Return the index of the specified filename
function! s:Tlist_Get_File_Index(fname)
    let i 
= 0

    
" Do a linear search
    while i < s:tlist_file_count
        if s:tlist_{i}_filename == a:fname
            return i
        endif
        let i = i + 1
    endwhile

    return -1
endfunction

" Tlist_Get_File_Index_By_Linenum()
" Return the index of the filename present in the specified line number
function! s:Tlist_Get_File_Index_By_Linenum(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
        endif
        let i 
= i + 1
    endwhile

    
return -1
endfunction

" Tlist_Skip_File()
" Check whether tag listing is supported for the specified file
function! s:Tlist_Skip_File(filename, ftype)
    
" Skip buffers with filetype not set
    if a:ftype == ''
        return 1
    endif

    
" Skip files which are not supported by exuberant ctags
    
" First check whether default settings for this filetype are available.
    
" If it is not available, then check whether user specified settings are
    
" available. If both are not available, then don't list the tags for this
    
" filetype
    let 
var = 's:tlist_def_' . a:ftype . '_settings'
    
if !exists(var)
        let 
var = 'g:tlist_' . a:ftype . '_settings'
        
if !exists(var)
            
return 1
        endif
    endif

    
" Skip buffers with no names
    if a:filename == ''
        return 1
    endif

    
" Skip files which are not readable or files which are not yet stored
    
" to the disk
    if !filereadable(a:filename)
        return 1
    endif

    return 0
endfunction

" Tlist_FileType_Init
" Initialize the ctags arguments and tag variable for the specified
" file type
function! s:Tlist_FileType_Init(ftype)
    
" If the user didn't specify any settings, then use the default
    
" ctags args. Otherwise, use the settings specified by the user
    let 
var = 'g:tlist_' . a:ftype . '_settings'
    
if exists(var)
        
" User specified ctags arguments
        let settings = {var} . ';'
    else
        
" Default ctags arguments
        let 
var = 's:tlist_def_' . a:ftype . '_settings'
        
if !exists(var)
            
" No default settings for this file type. This filetype is
            
" not supported
            
return 0
        endif
        let settings 
= s:tlist_def_{a:ftype}_settings . ';'
    endif

    let msg 
= 'Invalid ctags option setting - ' . settings

    
" Format of the option that specifies the filetype and ctags arugments:
    
"
    
"       <language_name>;flag1:name1;flag2:name2;flag3:name3
    
"

    
" Extract the file type to pass to ctags. This may be different from the
    
" file type detected by Vim
    let pos 
= stridx(settings, ';')
    
if pos == -1
        call s:Tlist_Warning_Msg(msg)
        
return 0
    endif
    let ctags_ftype 
= strpart(settings, 0, pos)
    
if ctags_ftype == ''
        call s:Tlist_Warning_Msg(msg)
        
return 0
    endif
    
" Make sure a valid filetype is supplied. If the user didn't specify a
    
" valid filetype, then the ctags option settings may be treated as the
    
" filetype
    if ctags_ftype =~ ':'
        call s:Tlist_Warning_Msg(msg)
        return 0
    endif

    
" Remove the file type from settings
    let settings 
= strpart(settings, pos + 1)
    
if settings == ''
        call s:Tlist_Warning_Msg(msg)
        
return 0
    endif

    
" Process all the specified ctags flags. The format is
    
" flag1:name1;flag2:name2;flag3:name3
    let ctags_flags 
= ''
    let cnt 
= 0
    
while settings != ''
        
" Extract the flag
        let pos = stridx(settings, ':')
        if pos == -1
            call s:Tlist_Warning_Msg(msg)
            return 0
        endif
        let flag = strpart(settings, 0, pos) 
        if flag == ''
            call s:Tlist_Warning_Msg(msg)
            return 0
        endif
        
" Remove the flag from settings
        let settings 
= strpart(settings, pos + 1)

        
" Extract the tag type name
        let pos = stridx(settings, ';')
        if pos == -1
            call s:Tlist_Warning_Msg(msg)
            return 0
        endif
        let name = strpart(settings, 0, pos)
        if name == ''
            call s:Tlist_Warning_Msg(msg)
            return 0
        endif
        let settings = strpart(settings, pos + 1)

        let cnt = cnt + 1

        let s:tlist_{a:ftype}_{cnt}_name = flag
        let s:tlist_{a:ftype}_{cnt}_fullname = name
        let ctags_flags = ctags_flags . flag
    endwhile

    let s:tlist_{a:ftype}_ctags_args = '--language-force=' . ctags_ftype .
                            \ ' --' . ctags_ftype . '-types=' . ctags_flags
    let s:tlist_{a:ftype}_count = cnt
    let s:tlist_{a:ftype}_ctags_flags = ctags_flags

    
" Save the filetype name
    let s:tlist_ftype_{s:tlist_ftype_count}_name 
= a:ftype
    let s:tlist_ftype_count 
= s:tlist_ftype_count + 1

    
return 1
endfunction

" Tlist_Discard_TagInfo
" Discard the stored tag information for a file
function! s:Tlist_Discard_TagInfo(fidx)
    let ftype 
= s:tlist_{a:fidx}_filetype

    
" Discard information about the tags defined in the file
    let i = 1
    while i <= s:tlist_{a:fidx}_tag_count
        unlet s:tlist_{a:fidx}_tag_{i}
        let i = i + 1
    endwhile

    let s:tlist_{a:fidx}_tag_count = 0

    
" Discard information about tags groups by their type
    let i 
= 1
    
while i <= s:tlist_{ftype}_count
        let ttype 
= s:tlist_{ftype}_{i}_name
        
if s:tlist_{a:fidx}_{ttype} != ''
            let s:tlist_{a:fidx}_{ttype} 
= ''
            let s:tlist_{a:fidx}_{ttype}_start 
= 0
            let cnt 
= s:tlist_{a:fidx}_{ttype}_count
            let s:tlist_{a:fidx}_{ttype}_count 
= 0
            let j 
= 1
            
while j <= cnt
                unlet s:tlist_{a:fidx}_{ttype}_{j}
                let j 
= j + 1
            endwhile
        endif
        let i 
= i + 1
    endwhile
endfunction

" Tlist_Update_Line_Offsets
" Update the line offsets for tags for files starting from start_idx
" and displayed in the taglist window by the specified offset
function! s:Tlist_Update_Line_Offsets(start_idx, increment, offset)
    let i = a:start_idx

    while i < s:tlist_file_count
        if s:tlist_{i}_visible
            
" Update the start/end line number only if the file is visible
            
if a:increment
                let s:tlist_{i}_start 
= s:tlist_{i}_start + a:offset
                let s:tlist_{i}_end 
= s:tlist_{i}_end + a:offset
            
else
                let s:tlist_{i}_start 
= s:tlist_{i}_start - a:offset
                let s:tlist_{i}_end 
= s:tlist_{i}_end - a:offset
            endif
        endif
        let i 
= i + 1
    endwhile
endfunction

" Tlist_Discard_FileInfo
" Discard the stored information for a file
function! s:Tlist_Discard_FileInfo(fidx)
    call s:Tlist_Discard_TagInfo(a:fidx)

    let ftype 
= s:tlist_{a:fidx}_filetype

    let i 
= 1
    
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}_count
        let i 
= i + 1
    endwhile

    unlet s:tlist_{a:fidx}_filename
    unlet s:tlist_{a:fidx}_sort_type
    unlet s:tlist_{a:fidx}_filetype
    unlet s:tlist_{a:fidx}_start
    unlet s:tlist_{a:fidx}_end
    unlet s:tlist_{a:fidx}_valid
    unlet s:tlist_{a:fidx}_visible
    unlet s:tlist_{a:fidx}_tag_count
endfunction

" Tlist_Remove_File_From_Display
" Remove the specified file from display
function! s:Tlist_Remove_File_From_Display(fidx)
    
" Remove the tags displayed for the specified file from the window
    let start = s:tlist_{a:fidx}_start
    
" Include the empty line after the last line also
    
if g:Tlist_Compact_Format
        let end 
= s:tlist_{a:fidx}_end
    
else
        let end 
= s:tlist_{a:fidx}_end + 1
    endif

    setlocal modifiable

    exe 'silent
! ' . start . ',' . end . 'delete _'

    setlocal nomodifiable

    
" Correct the start and end line offsets for all the files following
    
" this file, as the tags for this file are removed
    call s:Tlist_Update_Line_Offsets(a:fidx 
+ 10, end - start + 1)
endfunction

" Tlist_Remove_File
" Remove the file under the cursor or the specified file index
function! s:Tlist_Remove_File(file_idx, update_display)
    
if a:file_idx == -1
        let fidx 
= s:Tlist_Get_File_Index_By_Linenum(line('.'))
        
if fidx == -1
            
return
        endif
    
else
        let fidx 
= a:file_idx
    endif

    
if a:update_display
        call s:Tlist_Remove_File_From_Display(fidx)
    endif

    call s:Tlist_Discard_FileInfo(fidx)

    
" Shift all the file variables by one index
    let i = fidx + 1

    while i < s:tlist_file_count
        let j = i - 1

        let s:tlist_{j}_filename = s:tlist_{i}_filename
        let s:tlist_{j}_sort_type = s:tlist_{i}_sort_type
        let s:tlist_{j}_filetype = s:tlist_{i}_filetype
        let s:tlist_{j}_start = s:tlist_{i}_start
        let s:tlist_{j}_end = s:tlist_{i}_end
        let s:tlist_{j}_valid = s:tlist_{i}_valid
        let s:tlist_{j}_visible = s:tlist_{i}_visible
        let s:tlist_{j}_tag_count = s:tlist_{i}_tag_count

        let k = 1
        while k <= s:tlist_{j}_tag_count
            let s:tlist_{j}_tag_{k} = s:tlist_{i}_tag_{k}
            let k = k + 1
        endwhile

        let ftype = s:tlist_{i}_filetype

        let k = 1
        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}_count = s:tlist_{i}_{ttype}_count
            if s:tlist_{j}_{ttype} != ''
                let l = 1
                while l <= s:tlist_{j}_{ttype}_count
                    let s:tlist_{j}_{ttype}_{l} = s:tlist_{i}_{ttype}_{l}
                    let l = l + 1
                endwhile
            endif
            let k = k + 1
        endwhile

        call s:Tlist_Discard_FileInfo(i)

        let i = i + 1
    endwhile

    
" Reduce the number of files displayed
    let s:tlist_file_count 
= s:tlist_file_count - 1
endfunction


" Tlist_Open_Window
" Create a new taglist window. If it is already open, clear it
function! s:Tlist_Open_Window()
    
" If used with winmanager don't open windows. Winmanager will handle
    
" the window/buffer management
    
if s:tlist_part_of_winmanager
        
return
    endif

    
" Cleanup the taglist window listing, if the window is open
    let winnum = bufwinnr(g:TagList_title)
    if winnum != -1
        
" Jump to the existing window
        
if winnr() != winnum
            exe winnum . 'wincmd w'
        endif
    
else
        
" Create a new window. If user prefers a horizontal window, then open
        
" a horizontally split window. Otherwise open a vertically split
        
" window
        if g:Tlist_Use_Horiz_Window
            
" Open a horizontally split window
            let win_dir 
= 'botright'
            
" Horizontal window height
            let win_size = g:Tlist_WinHeight
        else
            
" Open a horizontally split window. Increase the window size, if
            
" needed, to accomodate the new window
            if g:Tlist_Inc_Winwidth &&
                        \ &columns < (80 + g:Tlist_WinWidth)
                
" one extra column is needed to include the vertical split
                let 
&columns= &columns + (g:Tlist_WinWidth + 1)
                let s:tlist_winsize_chgd 
= 1
            
else
                let s:tlist_winsize_chgd 
= 0
            endif

            
if g:Tlist_Use_Right_Window
                
" Open the window at the rightmost place
                let win_dir = 'botright vertical'
            else
                
" Open the window at the leftmost place
                let win_dir 
= 'topleft vertical'
            endif
            let win_size 
= g:Tlist_WinWidth
        endif

        
" If the tag listing temporary buffer already exists, then reuse it.
        
" Otherwise create a new buffer
        let bufnum 
= bufnr(g:TagList_title)
        
if bufnum == -1
            
" Create a new buffer
            let wcmd = g:TagList_title
        else
            
" Edit the existing buffer
            let wcmd 
= '+buffer' . bufnum
        endif

        
" Create the taglist window
        exe 'silent! ' . win_dir . ' ' . win_size . 'split ' . wcmd
    endif
endfunction

" Tlist_Zoom_Window
" Zoom (maximize/minimize) the taglist window
function! s:Tlist_Zoom_Window()
    if s:tlist_win_maximized
        
" Restore the window back to the previous size
        
if g:Tlist_Use_Horiz_Window
            exe 'resize ' . g:Tlist_WinHeight
        
else
            exe 'vert resize ' . g:Tlist_WinWidth
        endif
        let s:tlist_win_maximized 
= 0
    
else
        
" Set the window size to the maximum possible without closing other
        
" windows
        
if g:Tlist_Use_Horiz_Window
            resize
        
else
            vert resize
        endif
        let s:tlist_win_maximized 
= 1
    endif
endfunction

" Tlist_Init_Window
" Set the default options for the taglist window
function! s:Tlist_Init_Window()
    
" Set report option to a huge value to prevent informational messages
    
" while deleting the lines
    let old_report 
= &report
    set report
=99999

    
" Mark the buffer as modifiable
    setlocal modifiable

    
" Delete the contents of the buffer to the black-hole register
    silent
! %delete _

    
" Mark the buffer as not modifiable
    setlocal nomodifiable

    
" Restore the report option
    let 
&report = old_report

    
" Mark the buffer as modifiable
    setlocal modifiable

    if g:Tlist_Compact_Format == 0
        
" Display help in non-compact mode
        call s:Tlist_Display_Help()
    endif

    
" Mark the buffer as not modifiable
    setlocal nomodifiable

    
" Define taglist window element highlighting
    
if has('syntax')
        syntax match TagListComment '
^" .*'
        syntax match TagListFileName '^[^
" ].*$'
        syntax match TagListTitle '
^  \S.*$'
        syntax match TagListTagScope  '\s\[.\{
-\}\]$'

        
" Define the highlighting only if colors are supported
        if has('gui_running') || &t_Co > 2
            
" Colors to highlight various taglist window elements
            
" If user defined highlighting group exists, then use them.
            
" Otherwise, use default highlight groups.
            
if hlexists('MyTagListTagName')
                highlight link TagListTagName MyTagListTagName
            
else
                highlight 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
            endif
            if hlexists('MyTagListTitle')
                highlight link TagListTitle MyTagListTitle
            else
                highlight clear TagListTitle
                highlight link TagListTitle Title
            endif
            if hlexists('MyTagListFileName')
                highlight link TagListFileName MyTagListFileName
            else
                highlight clear TagListFileName
                highlight link TagListFileName LineNr
            endif
            if hlexists('MyTagListTagScope')
                highlight link TagListTagScope MyTagListTagScope
            else
                highlight clear TagListTagScope
                highlight link TagListTagScope Identifier
            endif
        else
            highlight TagListTagName term=reverse cterm=reverse
        endif
    endif

    
" Folding related settings
    
if has('folding')
        setlocal foldenable
        setlocal foldmethod
=manual
        setlocal foldcolumn
=3
        setlocal foldtext
=v:folddashes.getline(v:foldstart)
    endif

    
if !s:tlist_part_of_winmanager
    
" Mark buffer as scratch
    silent! setlocal buftype=nofile
    silent! setlocal bufhidden=delete
    silent! setlocal noswapfile
    
" Due to a bug in Vim 6.0, the winbufnr() function fails for unlisted
    
" buffers. So if the taglist buffer is unlisted, multiple taglist
    
" windows will be opened. This bug is fixed in Vim 6.1 and above
    
if v:version >= 601
        silent
! setlocal nobuflisted
    endif
    endif

    silent
! setlocal nowrap

    
" If the 'number' option is set in the source window, it will affect the
    
" taglist window. So forcefully disable 'number' option for the taglist
    
" window
    silent! setlocal nonumber

    
" Create buffer local mappings for jumping to the tags and sorting the list
    nnoremap 
<buffer> <silent> <CR> :call <SID>Tlist_Jump_To_Tag(0)<CR>
    nnoremap 
<buffer> <silent> o :call <SID>Tlist_Jump_To_Tag(1)<CR>
    nnoremap 
<buffer> <silent> p :call <SID>Tlist_Jump_To_Tag(2)<CR>
    nnoremap 
<buffer> <silent> <2-LeftMouse> :call <SID>Tlist_Jump_To_Tag(0)<CR>
    nnoremap 
<buffer> <silent> s :call <SID>Tlist_Change_Sort()<CR>
    nnoremap 
<buffer> <silent> + :silent! foldopen<CR>
    nnoremap 
<buffer> <silent> - :silent! foldclose<CR>
    nnoremap 
<buffer> <silent> * :silent! %foldopen!<CR>
    nnoremap 
<buffer> <silent> = :silent! %foldclose!<CR>
    nnoremap 
<buffer> <silent> <kPlus> :silent! foldopen<CR>
    nnoremap 
<buffer> <silent> <kMinus> :silent! foldclose<CR>
    nnoremap 
<buffer> <silent> <kMultiply> :silent! %foldopen!<CR>
    nnoremap 
<buffer> <silent> <Space> :call <SID>Tlist_Show_Tag_Prototype()<CR>
    nnoremap 
<buffer> <silent> u :call <SID>Tlist_Update_Window()<CR>
    nnoremap 
<buffer> <silent> d :call <SID>Tlist_Remove_File(-11)<CR>
    nnoremap 
<buffer> <silent> x :call <SID>Tlist_Zoom_Window()<CR>
    nnoremap 
<buffer> <silent> ? :call <SID>Tlist_Toggle_Help_Text()<CR>
    nnoremap 
<buffer> <silent> q :close<CR>

    
" Insert mode mappings
    inoremap <buffer> <silent> <CR>    <C-o>:call <SID>Tlist_Jump_To_Tag(0)<CR>
    
" Windows needs return
    inoremap 
<buffer> <silent> <Return> <C-o>:call <SID>Tlist_Jump_To_Tag(0)<CR>
    inoremap 
<buffer> <silent> o        <C-o>:call <SID>Tlist_Jump_To_Tag(1)<CR>
    inoremap 
<buffer> <silent> p        <C-o>:call <SID>Tlist_Jump_To_Tag(2)<CR>
    inoremap 
<buffer> <silent> <2-LeftMouse> <C-o>:call 
                                            \ 
<SID>Tlist_Jump_To_Tag(0)<CR>
    inoremap 
<buffer> <silent> s        <C-o>:call <SID>Tlist_Change_Sort()<CR>
    inoremap 
<buffer> <silent> +             <C-o>:silent! foldopen<CR>
    inoremap 
<buffer> <silent> -             <C-o>:silent! foldclose<CR>
    inoremap 
<buffer> <silent> *             <C-o>:silent! %foldopen!<CR>
    inoremap 
<buffer> <silent> =             <C-o>:silent! %foldclose!<CR>
    inoremap 
<buffer> <silent> <kPlus>       <C-o>:silent! foldopen<CR>
    inoremap 
<buffer> <silent> <kMinus>      <C-o>:silent! foldclose<CR>
    inoremap 
<buffer> <silent> <kMultiply>   <C-o>:silent! %foldopen!<CR>
    inoremap 
<buffer> <silent> <Space>       <C-o>:call 
                                    \ 
<SID>Tlist_Show_Tag_Prototype()<CR>
    inoremap 
<buffer> <silent> u    <C-o>:call <SID>Tlist_Update_Window()<CR>
    inoremap 
<buffer> <silent> d    <C-o>:call <SID>Tlist_Remove_File(-11)<CR>
    inoremap 
<buffer> <silent> x    <C-o>:call <SID>Tlist_Zoom_Window()<CR>
    inoremap 
<buffer> <silent> ?    <C-o>:call <SID>Tlist_Toggle_Help_Text()<CR>
    inoremap 
<buffer> <silent> q    <C-o>:close<CR>

    
" Map single left mouse click if the user wants this functionality
    if g:Tlist_Use_SingleClick
    nnoremap <silent> <LeftMouse> <LeftMouse>:if bufname(
"%") =~ "__Tag_List__"
                        \ <bar> call <SID>Tlist_Jump_To_Tag(0) <bar> endif <CR>
    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()
        
" Highlight the current tag 
        autocmd CursorHold 
* silent call <SID>Tlist_Highlight_Tag(
                                \ fnamemodify(bufname('
%'), ':p'), line('.'))
        
" Adjust the Vim window width when taglist window is closed
        autocmd BufUnload __Tag_List__ call <SID>Tlist_Post_Close_Cleanup()
        
" Exit Vim itself if only the taglist window is present (optional)
        autocmd BufEnter __Tag_List__ call 
<SID>Tlist_Check_Only_Window()
        
if !s:tlist_part_of_winmanager
            
" Auto refresh the taglist window
            autocmd BufEnter * call <SID>Tlist_Refresh_Window()
        endif
    augroup end

    
" List all the tags for the previously processed files
    let i 
= 0
    
while i < s:tlist_file_count
        
" Mark the file as not visible, so that Tlist_Explore_File() will
        
" display the tags for this file and mark the file as visible
        let s:tlist_{i}_visible 
= 0
        call s:Tlist_Explore_File(s:tlist_{i}_filename, s:tlist_{i}_filetype)
        let i 
= i + 1
    endwhile
endfunction

" Tlist_Post_Close_Cleanup()
" Close the taglist window and adjust the Vim window width
function! s:Tlist_Post_Close_Cleanup()
    
" Mark all the files as not visible
    let i = 0
    while i < s:tlist_file_count
        let s:tlist_{i}_visible = 0
        let i = i + 1
    endwhile

    
" Remove the taglist autocommands
    silent
! autocmd! TagListAutoCmds

    
" Clear all the highlights
    match none

    if has('syntax')
        silent! syntax clear TagListTitle
        silent! syntax clear TagListComment
        silent! syntax clear TagListTagScope
    endif

    
" Remove the left mouse click mapping if it was setup initially
    
if g:Tlist_Use_SingleClick
        
if hasmapto('<LeftMouse>')
            nunmap 
<LeftMouse>
        endif
    endif

    
if !s:tlist_part_of_winmanager
    
if g:Tlist_Use_Horiz_Window || g:Tlist_Inc_Winwidth == 0 ||
                \ s:tlist_winsize_chgd 
== 0 ||
                \ 
&columns < (80 + g:Tlist_WinWidth)
        
" No need to adjust window width if using horizontally split taglist
        
" window or if columns is less than 101 or if the user chose not to
        
" adjust the window width
    else
        
" Adjust the Vim window width
        let 
&columns= &columns - (g:Tlist_WinWidth + 1)
    endif
    endif

    
" Reset taglist state variables
    let s:tlist_cur_fidx = -1
    if s:tlist_part_of_winmanager
        let s:tlist_part_of_winmanager = 0
        let s:tlist_window_initialized = 0
    endif
endfunction

" Tlist_Check_Only_Window
" Check if only the taglist window is opened currently. If the
" Tlist_Exit_OnlyWindow variable is set, then close the taglist window
function! s:Tlist_Check_Only_Window()
    
if g:Tlist_Exit_OnlyWindow
        
if winbufnr(2== -1 && bufname(winbufnr(1)) == g:TagList_title
            
" If only the taglist window is currently open, then the buffer
            
" number associated with window 2 will be -1.
            quit
        endif
    endif
endfunction

" Tlist_Explore_File()
" List the tags defined in the specified file in a Vim window
function! s:Tlist_Explore_File(filename, ftype)
    
" First check whether the file already exists
    let fidx = s:Tlist_Get_File_Index(a:filename)
    if fidx != -1
        let file_exists = 1
    else
        let file_exists = 0
    endif

    if file_exists && s:tlist_{fidx}_visible
        
" Check whether the file tags are currently valid
        
if s:tlist_{fidx}_valid
            
" Make the selected file as the current file
            let s:tlist_cur_fidx = fidx

            
" Goto the first line in the file
            exe s:tlist_{fidx}_start
            
return
        endif

        
" Discard and remove the tags for this file from display
        call s:Tlist_Discard_TagInfo(fidx)
        call s:Tlist_Remove_File_From_Display(fidx)
    endif

    
" Process and generate a list of tags defined in the file
    
if !file_exists || !s:tlist_{fidx}_valid
        let ret_fidx 
= s:Tlist_Process_File(a:filename, a:ftype)
        
if ret_fidx == -1
            
if file_exists
                
" If the tags for the file were previously displayed and now
                
" we are not able to get the tag information then discard the
                
" file information
                call s:Tlist_Remove_File(fidx, 0)
            endif
            return
        endif
        let fidx = ret_fidx
    endif

    
" Make the selected file as the current file
    let s:tlist_cur_fidx 
= fidx

    
" Set report option to a huge value to prevent informational messages
    
" while adding lines to the taglist window
    let old_report 
= &report
    set report
=99999

    
" Mark the buffer as modifiable
    setlocal modifiable

    
" Add new files to the end of the window. For existing files, add them at
    
" the same line where they were previously present. If the file is not
    
" visible, then add it at the end
    
if s:tlist_{fidx}_start == 0 || !s:tlist_{fidx}_visible
        
if g:Tlist_Compact_Format
            let s:tlist_{fidx}_start 
= line('$')
        
else
            let s:tlist_{fidx}_start 
= line('$') + 1
        endif
    endif

    let s:tlist_{fidx}_visible 
= 1

    
" Goto the line where this file should be placed
    if g:Tlist_Compact_Format
        exe s:tlist_{fidx}_start
    else
        exe (s:tlist_{fidx}_start - 1)
    endif

    let txt = fnamemodify(s:tlist_{fidx}_filename, ':t') . ' (' .
                \ fnamemodify(s:tlist_{fidx}_filename, ':p:h') . ')'
    if g:Tlist_Compact_Format == 0
        silent! put =txt
    else
        silent! put! =txt
        
" Move to the next line
        exe line('.') 
+ 1
    endif
    let file_start 
= s:tlist_{fidx}_start

    
" Add the tag names grouped by tag type to the buffer with a title
    let i = 1
    while i <= s:tlist_{a:ftype}_count
        let ttype = s:tlist_{a:ftype}_{i}_name
        
" Add the tag type only if there are tags for that type
        
if s:tlist_{fidx}_{ttype} != ''
            let txt 
= '  ' . s:tlist_{a:ftype}_{i}_fullname
            
if g:Tlist_Compact_Format == 0
                let ttype_start_lnum 
= line('.') + 1
                silent
! put =txt
            
else
                let ttype_start_lnum 
= line('.')
                silent
! put! =txt
            endif
            silent
! put =s:tlist_{fidx}_{ttype}

            
if g:Tlist_Compact_Format
                exe (line('.') 
+ s:tlist_{fidx}_{ttype}_count)
            endif

            let s:tlist_{fidx}_{ttype}_start 
= ttype_start_lnum - file_start

            
" create a fold for this tag type
            if has('folding')
                let fold_start = ttype_start_lnum
                let fold_end = fold_start + s:tlist_{fidx}_{ttype}_count
                exe fold_start . ',' . fold_end  . 'fold'
            endif

            if g:Tlist_Compact_Format == 0
                silent! put =''
            endif
        endif
        let i = i + 1
    endwhile

    if s:tlist_{fidx}_tag_count == 0
        put =''
    endif

    let s:tlist_{fidx}_end = line('.') - 1

    
" Create a fold for the entire file
    
if has('folding')
        exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'fold'
        exe 'silent
! ' . s:tlist_{fidx}_start . ',' . 
                                        \ s:tlist_{fidx}_end . 'foldopen
!'
    endif

    
" Goto the starting line for this file,
    exe s:tlist_{fidx}_start

    if s:tlist_part_of_winmanager
        
" To handle a bug in the winmanager plugin, add a space at the
        
" last line
        call setline('$', ' ')
    endif

    
" Mark the buffer as not modifiable
    setlocal nomodifiable

    
" Restore the report option
    let &report = old_report

    
" Update the start and end line numbers for all the files following this
    
" file
    let start = s:tlist_{fidx}_start
    
" include the empty line after the last line
    
if g:Tlist_Compact_Format
        let end 
= s:tlist_{fidx}_end
    
else
        let end 
= s:tlist_{fidx}_end + 1
    endif
    call s:Tlist_Update_Line_Offsets(fidx 
+ 11, end - start + 1)

    
return
endfunction

" Tlist_Init_File
" Initialize the variables for a new file
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

    
" Initialize the file variables
    let s:tlist_{fidx}_filename 
= a:filename
    let s:tlist_{fidx}_sort_type 
= g:Tlist_Sort_Type
    let s:tlist_{fidx}_filetype 
= a:ftype
    let s:tlist_{fidx}_start 
= 0
    let s:tlist_{fidx}_end 
= 0
    let s:tlist_{fidx}_valid 
= 0
    let s:tlist_{fidx}_visible 
= 0
    let s:tlist_{fidx}_tag_count 
= 0

    
" Initialize the tag type variables
    let i = 1
    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}_count = 0
        let i = i + 1
    endwhile

    return fidx
endfunction

" Tlist_Process_File
" Get the list of tags defined in the specified file and store them
" in Vim variables. Returns the file index where the tags are stored.
function! s:Tlist_Process_File(filename, ftype)
    
" Check for valid filename and valid filetype
    if a:filename == '' || !filereadable(a:filename) || a:ftype == ''
        return -1
    endif

    
" If the tag types for this filetype are not yet created, then create
    
" them now
    let var = 's:tlist_' . a:ftype . '_count'
    if !exists(var)
        if s:Tlist_FileType_Init(a:ftype) == 0
            return -1
        endif
    endif

    
" If this file is already processed, then use the cached values
    let fidx 
= s:Tlist_Get_File_Index(a:filename)
    
if fidx == -1
        
" First time, this file is loaded
        let fidx = s:Tlist_Init_File(a:filename, a:ftype)
    endif

    let s:tlist_{fidx}_valid = 1

    
" Exuberant ctags arguments to generate a tag list
    let ctags_args 
= ' -- --format=2 --excmd=pattern --fields=nks '

    
" Form the ctags argument depending on the sort type 
    if s:tlist_{fidx}_sort_type == 'name'
        let ctags_args = ctags_args . ' --sort=yes '
    else
        let ctags_args = ctags_args . ' --sort=no '
    endif

    
" Add the filetype specific arguments
    let ctags_args 
= ctags_args . ' ' . s:tlist_{a:ftype}_ctags_args

    
" Ctags command to produce output with regexp for locating the tags
    let ctags_cmd = g:Tlist_Ctags_Cmd . ctags_args
    let ctags_cmd = ctags_cmd . ' 
"' . a:filename . '"'

    
" In Windows 95if not using cygwin, disable the 'shellslash'
    
" option. Otherwise, this will cause problems when running the
    
" ctags command.
    
if has("win95"&& !has("win32unix")
        let myshellslash 
= &shellslash
        set noshellslash
    endif

    
" Run ctags and get the tag list
    let cmd_output = system(ctags_cmd)

    
" Restore the value of the 'shellslash' option.
    
if has("win95"&& !has("win32unix")
        let 
&shellslash = myshellslash
    endif

    
" Handle errors
    if v:shell_error && cmd_output != ''
        call s:Tlist_Warning_Msg(cmd_output)
        return -1
    endif

    
" No tags for current file
    
if cmd_output == ''
        call s:Tlist_Warning_Msg('No tags found 
for ' . a:filename)
        
return -1
    endif

    
" Process the ctags output one line at a time. Separate the tag output
    
" based on the tag type and store it in the tag type variable
    
" The format of each line in the ctags output is:
    
"
    
"     tag_name<TAB>file_name<TAB>ex_cmd;"<TAB>extension_fields 
    
"
    while cmd_output != ''
        
" Extract one line at a time
        let one_line 
= strpart(cmd_output, 0, stridx(cmd_output, "\n"))
        
" Remove the line from the tags output
        let cmd_output = strpart(cmd_output, stridx(cmd_output, 
"\n") + 1)

        if one_line == ''
            
" Line is not in proper tags format
            
continue
        endif

        
" Extract the tag type
        let ttype = s:Tlist_Extract_Tagtype(one_line)

        if ttype == ''
            
" Line is not in proper tags format
            
continue
        endif

        
" make sure the tag type is supported
        if s:tlist_{a:ftype}_ctags_flags !~# ttype
            continue
        endif

        
" Extract the tag name
        
if g:Tlist_Display_Prototype == 0
            let ttxt 
= '    ' . strpart(one_line, 0, stridx(one_line, "\t"))

            
" Add the tag scope, if it is available. Tag scope is the last
            
" field after the 'line:<num>\t' field
            
if g:Tlist_Display_Tag_Scope     " only if it is selected
                let start = strridx(one_line, 'line:')
                let end = strridx(one_line, 
"\t")
                if end > start
                    let tscope = strpart(one_line, end + 1)
                    let tscope = strpart(tscope, stridx(tscope, ':') + 1)
                    if tscope != ''
                        let ttxt = ttxt . ' [' . tscope . ']'
                    endif
                endif
            endif
        else
            let start = stridx(one_line, '/^') + 2
            let end = strridx(one_line, '/;
"' . "\t")
            
" The search patterns for some tag types doesn't end with 
            
" the ;" character
            if one_line[end - 1] == '$'
                let end = end -1
            endif
            let ttxt = strpart(one_line, start, end - start)
        endif

        
" Update the count of this tag type
        let cnt 
= s:tlist_{fidx}_{ttype}_count + 1
        let s:tlist_{fidx}_{ttype}_count 
= cnt

        
" Add this tag to the tag type variable
        let s:tlist_{fidx}_{ttype} = s:tlist_{fidx}_{ttype} . ttxt . 
"\n"

        
" Update the total tag count
        let s:tlist_{fidx}_tag_count 
= s:tlist_{fidx}_tag_count + 1
        
" Store the ctags output line and the tagtype count
        let s:tlist_{fidx}_tag_{s:tlist_{fidx}_tag_count} = 
                                    \ cnt . ':' . one_line
        
" Store the tag output index
        let s:tlist_{fidx}_{ttype}_{cnt} 
= s:tlist_{fidx}_tag_count
    endwhile

    
return fidx
endfunction

" Tlist_Close_Window
" Close the taglist window
function! s:Tlist_Close_Window()
    
" Make sure the taglist window exists
    let winnum = bufwinnr(g:TagList_title)
    if winnum == -1
        call s:Tlist_Warning_Msg('Error: Taglist window is not open')
        return
    endif

    if winnr() == winnum
        
" Already in the taglist window. Close it and return
        close
    
else
        
" Goto the taglist window, close it and then come back to the
        
" original window
        let curbufnr 
= bufnr('%')
        exe winnum . 'wincmd w'
        close
        
" Need to jump back to the original window only if we are not
        
" already in that window
        let winnum 
= bufwinnr(curbufnr)
        
if winnr() != winnum
            exe winnum . 'wincmd w'
        endif
    endif
endfunction

" Tlist_Toggle_Window()
" Open or close a taglist window
function! s:Tlist_Toggle_Window(bufnum)
    let curline 
= line('.')

    
" If taglist window is open then close it.
    let winnum = bufwinnr(g:TagList_title)
    if winnum != -1
        call s:Tlist_Close_Window()
        return
    endif

    
" We are not part of winmanager plugin
    let s:tlist_part_of_winmanager 
= 0

    
" Get the filename and filetype for the specified buffer
    let filename = fnamemodify(bufname(a:bufnum), ':p')
    let ftype = getbufvar(a:bufnum, '&filetype')

    
" Mark the current window as the desired window to open a file
    
" when a tag is selcted
    let w:tlist_file_window = 
"yes"

    
" Open the taglist window
    call s:Tlist_Open_Window()

    
" Initialize the taglist window
    call s:Tlist_Init_Window()

    
" List the tags defined in the file
    call s:Tlist_Explore_File(filename, ftype)

    
" Highlight the current tag
    call s:Tlist_Highlight_Tag(filename, curline)

    
" Go back to the original window
    let s:Tlist_Skip_Refresh 
= 1
    wincmd p
    let s:Tlist_Skip_Refresh 
= 0
endfunction

" Tlist_Extract_Tagtype
" Extract the tag type from the tag text
function! s:Tlist_Extract_Tagtype(tag_txt)
    
" The tag type is after the tag prototype field. The prototype field
    
" ends with the /;"\t string. We add 4 at the end to skip the characters
    
" in this special string..
    let start 
= strridx(a:tag_txt, '/;"' . "\t") + 4
    let end = strridx(a:tag_txt, 'line:') - 1
    let ttype = strpart(a:tag_txt, start, end - start)

    return ttype
endfunction

" Tlist_Extract_Tag_Prototype
" Extract the tag protoype from the tag text
function! s:Tlist_Extract_Tag_Prototype(tag_txt)
    let start = stridx(a:tag_txt, '/^') + 2
    let end = strridx(a:tag_txt, '/;
"' . "\t")
    
if a:tag_txt[end - 1== '$'
        let end 
= end -1
    endif
    let tag_pat 
= strpart(a:tag_txt, start, end - start)

    
" Remove all the leading space characters
    let tag_pat = matchstr(tag_pat, '^\s*\zs.*')

    return tag_pat
endfunction

" Tlist_Add_File()
" Add a new file to the taglist
function! s:Tlist_Add_File(filename, ftype)
    
" Goto the taglist window
    call s:Tlist_Open_Window()

    
" Update the taglist window
    call s:Tlist_Explore_File(a:filename, a:ftype)
endfunction

" Tlist_Refresh_Window()
" Refresh the taglist window
function! s:Tlist_Refresh_Window()
    
" If we are entering the buffer from one of the taglist functions, then
    
" no need to refresh the taglist window again.
    if s:Tlist_Skip_Refresh
        return
    endif

    
" Skip buffers with 'buftype' set to nofile, nowrite, quickfix or help
    
if &buftype != ''
        
return
    endif

    let filename 
= fnamemodify(bufname('%'), ':p')
    let ftype 
= &filetype

    
" If the file doesn't support tag listing, skip it
    if s:Tlist_Skip_File(filename, ftype)
        return
    endif

    let curline = line('.')

    
" Make sure the taglist window is open. Otherwise, no need to refresh
    let winnum 
= bufwinnr(g:TagList_title)
    
if winnum == -1
        
return
    endif

    let fidx 
= s:Tlist_Get_File_Index(filename)
    
if fidx != -1 && s:tlist_cur_fidx == fidx
        
" If the tag listing for the current window is already present, no
        
" need to refresh it
        
return
    endif

    
" Save the current window number
    let cur_winnr = winnr()

    
" Goto the taglist window
    call s:Tlist_Open_Window()

    
" Update the taglist window
    call s:Tlist_Explore_File(filename, ftype)

    
" Highlight the current tag
    call s:Tlist_Highlight_Tag(filename, curline)

    
" Refresh the taglist window
    redraw

    if !s:tlist_part_of_winmanager
    
" Jump back to the original window
    exe cur_winnr . 'wincmd w'
    endif
endfunction

" Tlist_Change_Sort()
" Change the sort order of the tag listing
function! s:Tlist_Change_Sort()
    
if s:tlist_cur_fidx == -1
        
return
    endif

    
" Remove the previous highlighting
    match none

    let fidx = s:tlist_cur_fidx

    let sort_type = s:tlist_{fidx}_sort_type

    
" Toggle the sort order from 'name' to 'order' and vice versa
    
if sort_type == 'name'
        let s:tlist_{fidx}_sort_type 
= 'order'
    
else
        let s:tlist_{fidx}_sort_type 
= 'name'
    endif

    
" Save the current line for later restoration
    let curline = '\V\^' . getline('.') . '\$'

    
" Invalidate the tags listed for this file
    let s:tlist_{fidx}_valid 
= 0

    call s:Tlist_Explore_File(s:tlist_{fidx}_filename, s:tlist_{fidx}_filetype)

    
" Go back to the tag line before the list is sorted
    call search(curline, 'w')
endfunction

" Tlist_Update_Tags()
" Update taglist for the current buffer by regenerating the tag list
" Contributed by WEN Guopeng.
function! s:Tlist_Update_Tags()
    
" If taglist window is not open, show an error message:
    let winnum = bufwinnr(g:TagList_title)
    if winnum == -1
        call s:Tlist_Warning_Msg('Error: Taglist window is not open')
        return 0
    endif

    
" Update the tag list window only if it's open
    
if winnr() == winnum
        
" Already in the taglist window, simply update the window content
        call s:Tlist_Update_Window()
    else
        
" First check the current buffer is modified or not:
        
if &modified
            let msg 
= "No write since last change, tag list may be inaccurate"
            call s:Tlist_Warning_Msg(msg)
        endif

        
" Goto the taglist window, update it and get back to the original
        
" window:
        let curbufnr 
= bufnr('%')
        exe winnum . 'wincmd w'
        call s:Tlist_Update_Window()

        
" Need to jump back to the original window only if we are not
        
" already in that window
        let winnum 
= bufwinnr(curbufnr)
        
if winnr() != winnum
            exe winnum . 'wincmd w'
        endif
    endif

    
return 1
endfunction

" Tlist_Update_Window()
" Update the window by regenerating the tag list
function! s:Tlist_Update_Window()
    let fidx 
= s:Tlist_Get_File_Index_By_Linenum(line('.'))
    
if fidx == -1
        
return
    endif

    
" Remove the previous highlighting
    match none

    
" Save the current line for later restoration
    let curline 
= '\V\^' . getline('.') . '\$'

    let s:tlist_{fidx}_valid 
= 0

    
" Update the taglist window
    call s:Tlist_Explore_File(s:tlist_{fidx}_filename, s:tlist_{fidx}_filetype)

    
" Go back to the tag line before the list is sorted
    call search(curline, 'w')
endfunction

" Tlist_Get_Tag_Index()
" Return the tag index for the current line
function! s:Tlist_Get_Tag_Index(fidx)
    let lnum 
= line('.')
    let ftype 
= s:tlist_{a:fidx}_filetype

    
" Determine to which tag type the current line number belongs to using the
    
" tag type start line number and the number of tags in a tag type
    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 end 
=  start_lnum + s:tlist_{a:fidx}_{ttype}_count
        
if lnum >= start_lnum && lnum <= end
            
break
        endif
        let i 
= i + 1
    endwhile

    
" Current line doesn't belong to any of the displayed tag types
    if i > s:tlist_{ftype}_count
        return 0
    endif

    
" Compute the index into the displayed tags for the tag type
    let tidx 
= lnum - start_lnum
    
if tidx == 0
        
return 0
    endif

    
" Get the corresponding tag line and return it
    return s:tlist_{a:fidx}_{ttype}_{tidx}
endfunction

" Tlist_Highlight_Tagline
" Higlight the current tagline
function! s:Tlist_Highlight_Tagline()
    
" Clear previously selected name
    match none

    
" Highlight the current selected name
    if g:Tlist_Display_Prototype == 0
        exe 'match TagListTagName /\%' . line('.') . 'l\s\+\zs.*/'
    else
        exe 'match TagListTagName /\%' . line('.') . 'l.*/'
    endif
endfunction

" Tlist_Jump_To_Tag()
" Jump to the location of the current tag
" win_ctrl == 0 - Reuse the existing file window
" win_ctrl == 1 - Open a new window
" win_ctrl == 2 - Preview the tag
function! s:Tlist_Jump_To_Tag(win_ctrl)
    
" Do not process comment lines and empty lines
    let curline = getline('.')
    if curline =~ '^\s*$' || curline[0] == '
"'
        
return
    endif

    
" If inside a fold, then don't try to jump to the tag
    if foldclosed('.') != -1
        return
    endif

    let fidx = s:Tlist_Get_File_Index_By_Linenum(line('.'))
    if fidx == -1
        return
    endif

    if fidx != s:tlist_cur_fidx
        
" Selected a tag from some other file. Switch to editing this file
        let s:tlist_cur_fidx 
= fidx
    endif

    
" Get the tag output for the current tag
    let tidx = s:Tlist_Get_Tag_Index(fidx)
    if tidx != 0
        let fidx = s:tlist_cur_fidx
        let mtxt = s:tlist_{fidx}_tag_{tidx}
        let start = stridx(mtxt, '/^') + 2
        let end = strridx(mtxt, '/;
"' . "\t")
        
if mtxt[end - 1== '$'
            let end 
= end - 1
        endif
        let tagpat 
= '\V\^' . strpart(mtxt, start, end - start) .
                                            \ (mtxt[end] 
== '$' ? '\$' : '')

        
" Highlight the tagline
        call s:Tlist_Highlight_Tagline()
    else
        
" Selected a line which is not a tag name. Just edit the file
        let tagpat 
= ''
    endif

    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)
    let s:Tlist_Skip_Refresh = 1

    if s:tlist_part_of_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 i = 1
        while winbufnr(i) != -1
            if getwinvar(i, 'tlist_file_window') == 
"yes"
                let fwin_num = i
                break
            endif
            let i = i + 1
        endwhile

        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
            let w:tlist_file_window = 
"yes"
        endif
    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 != ''
        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 has('folding')
        
if foldlevel('.') != 0
            normal
! zv
        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'
    endif

    let s:Tlist_Skip_Refresh = 0
endfunction

" Tlist_Show_Tag_Prototype()
" Display the prototype of the tag under the cursor
function! s:Tlist_Show_Tag_Prototype()
    
" If we have already display prototype in the tag window, no need to
    
" display it in the status line
    if g:Tlist_Display_Prototype
        return
    endif

    
" Clear the previously displayed line
    echo

    
" Do not process comment lines and empty lines
    let curline = getline('.')
    if curline =~ '^\s*$' || curline[0] == '
"'
        
return
    endif

    
" If inside a fold, then don't display the prototype
    if foldclosed('.') != -1
        return
    endif

    
" Get the file index
    let fidx 
= s:Tlist_Get_File_Index_By_Linenum(line('.'))
    
if fidx == -1
        
return
    endif

    
" Get the tag output line for the current tag
    let tidx = s:Tlist_Get_Tag_Index(fidx)
    if tidx == 0
        return
    endif

    let mtxt = s:tlist_{fidx}_tag_{tidx}

    
" Get the tag search pattern and display it
    echo s:Tlist_Extract_Tag_Prototype(mtxt)
endfunction

" Tlist_Find_Tag_text
" Find the tag text given the line number in the source window
function! s:Tlist_Find_Tag_text(fidx, linenum)
    let sort_type 
= s:tlist_{a:fidx}_sort_type

    let left 
= 1
    let right 
= s:tlist_{a:fidx}_tag_count

    
if sort_type == 'order'
        
" Tag list sorted by order, do a binary search comparing the line
        
" numbers and pick a tag entry that contains the current line and
        
" highlight it.  The idea behind this function is taken from the
        
" ctags.vim script (by Alexey Marinichev) available at the Vim online
        
" website.

        
" If the current line is the less than the first tag, then no need to
        
" search
        let txt = s:tlist_{a:fidx}_tag_1
        let start = strridx(txt, 'line:') + strlen('line:')
        let end = strridx(txt, 
"\t")
        if end < start
            let first_lnum = strpart(txt, start) + 0
        else
            let first_lnum = strpart(txt, start, end - start) + 0
        endif

        if a:linenum < first_lnum
            return 
""
        endif

        while left < right
            let middle = (right + left + 1) / 2
            let txt = s:tlist_{a:fidx}_tag_{middle}

            let start = strridx(txt, 'line:') + strlen('line:')
            let end = strridx(txt, 
"\t")
            if end < start
                let middle_lnum = strpart(txt, start) + 0
            else
                let middle_lnum = strpart(txt, start, end - start) + 0
            endif

            if middle_lnum == a:linenum
                let left = middle
                break
            endif

            if middle_lnum > a:linenum
                let right = middle - 1
            else
                let left = middle
            endif
        endwhile
    else
        
" sorted by name, brute force method (Dave Eggum)
        let closest_lnum 
= 0
        let final_left 
= 0
        
while left < right
            let txt 
= s:tlist_{a:fidx}_tag_{left}

            let start 
= strridx(txt, 'line:') + strlen('line:')
            let end 
= strridx(txt, "\t")
            
if end < start
                let lnum 
= strpart(txt, start) + 0
            
else
                let lnum 
= strpart(txt, start, end - start) + 0
            endif

            
if lnum < a:linenum && lnum > closest_lnum
                let closest_lnum 
= lnum
                let final_left 
= left
            elseif lnum 
== a:linenum
                let closest_lnum 
= lnum
                
break
            
else
                let left 
= left + 1
            endif
        endwhile
        
if closest_lnum == 0
            
return ""
        endif
        
if left == right
            let left 
= final_left
        endif
    endif

    
return s:tlist_{a:fidx}_tag_{left}
endfunction

" Tlist_Highlight_Tag()
" Highlight the current tag
function! s:Tlist_Highlight_Tag(filename, curline)
    
if a:filename == ''
        
return
    endif

    
" Make sure the taglist window is present
    let winnum = bufwinnr(g:TagList_title)
    if winnum == -1
        call s:Tlist_Warning_Msg('Error: Taglist window is not open')
        return
    endif

    let fidx = s:Tlist_Get_File_Index(a:filename)
    if fidx == -1
        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_part_of_winmanager
        call WinManagerSuspendAUs()
    endif

    
" Save the original window number
    let org_winnr 
= winnr()

    
if org_winnr == winnum
        let in_taglist_window 
= 1
    
else
        let in_taglist_window 
= 0
    endif

    
" Go to the taglist window
    if !in_taglist_window
        exe winnum . 'wincmd w'
    endif

    
" Clear previously selected name
    match none

    let bno 
= bufnr(g:TagList_title)
    let tag_txt 
= s:Tlist_Find_Tag_text(fidx, a:curline)
    
if tag_txt == ""
        
" Make sure the current tag line is visible in the taglist window.
        
" Calling the winline() function makes the line visible.  Don't know
        
" of a better way to achieve this.
        call winline()

        if !in_taglist_window
            let s:Tlist_Skip_Refresh = 1
            exe org_winnr . 'wincmd w'
            let s:Tlist_Skip_Refresh = 0
        endif
        if s:tlist_part_of_winmanager
            call WinManagerResumeAUs()
        endif
        return
    endif

    
" Extract the tag type
    let ttype 
= s:Tlist_Extract_Tagtype(tag_txt)

    
" Extract the tag offset
    let offset = strpart(tag_txt, 0, stridx(tag_txt, ':')) + 0

    
" Compute the line number
    let lnum 
= s:tlist_{fidx}_start + s:tlist_{fidx}_{ttype}_start + offset

    
" Goto the line containing the tag
    exe lnum

    
" Open the fold
    
if has('folding')
        normal
! zv
    endif

    
" Make sure the current tag line is visible in the taglist window.
    
" Calling the winline() function makes the line visible.  Don't know
    
" of a better way to achieve this.
    call winline()

    
" Highlight the tag name
    call s:Tlist_Highlight_Tagline()

    
" Go back to the original window
    if !in_taglist_window
        let s:Tlist_Skip_Refresh = 1
        exe org_winnr . 'wincmd w'
        let s:Tlist_Skip_Refresh = 0
    endif

    if s:tlist_part_of_winmanager
        call WinManagerResumeAUs()
    endif

    return
endfunction

" Tlist_Get_Tag_Prototype_By_Line
" Get the prototype for the tag on or before the specified line number in the
" current buffer
function! s:Tlist_Get_Tag_Prototype_By_Line(linenum)
    
" Make sure the current file has a name
    let filename = fnamemodify(bufname(
"%"), ':p')
    if filename == ''
        return 
""
    endif

    let fidx = s:Tlist_Get_File_Index(filename)
    if fidx == -1
        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

    let linenr 
= a:linenum
    
if linenr == ""
        
" Default is the current line
        let linenr = line('.')
    endif

    
" Get the tag text using the line number
    let tag_txt 
= s:Tlist_Find_Tag_text(fidx, linenr)
    
if tag_txt == ""
        
return ""
    endif

    
" Extract the tag search pattern and return it
    return s:Tlist_Extract_Tag_Prototype(tag_txt)
endfunction

" Tlist_Session_Load
" Load a taglist session (information about all the displayed files
" and the tags) from the specified file
function! s:Tlist_Session_Load()
    
if a:0 == 0 || a:1 == ''
        call s:Tlist_Warning_Msg('Usage: TlistSessionLoad 
<filename>')
        
return
    endif

    let sessionfile 
= a:1

    
if !filereadable(sessionfile)
        call s:Tlist_Warning_Msg('Error: Unable to open file ' . sessionfile)
        
return
    endif

    
" Mark the current window as the file window
    if bufname('%') !~ g:TagList_title
        let w:tlist_file_window = 
"yes"
    endif

    
" Open to the taglist window
    call s:Tlist_Open_Window()

    
" Source the session file
    exe 'source ' . sessionfile

    let new_file_count = g:tlist_file_count
    unlet g:tlist_file_count

    let i = 0
    while i < new_file_count
        let ftype = g:tlist_{i}_filetype
        unlet g:tlist_{i}_filetype

        if !exists(
"s:tlist_" . ftype . "_count")
            if s:Tlist_FileType_Init(ftype) == 0
                let i = i + 1
                continue
            endif
        endif

        let fname = g:tlist_{i}_filename
        unlet g:tlist_{i}_filename

        let fidx = s:Tlist_Get_File_Index(fname)
        if fidx != -1
            let s:tlist_{fidx}_visible = 0
            let i = i + 1
            continue
        endif

        let fidx = s:Tlist_Init_File(fname, ftype)

        let s:tlist_{fidx}_filename = fname

        let s:tlist_{fidx}_sort_type = g:tlist_{i}_sort_type
        unlet g:tlist_{i}_sort_type

        let s:tlist_{fidx}_filetype = ftype

        let s:tlist_{fidx}_start = 0
        let s:tlist_{fidx}_end = 0

        let s:tlist_{fidx}_valid = 1
        
" Mark the file as not visible, so that Tlist_Init_Window() function
        
" will display the tags for this file
        let s:tlist_{fidx}_visible = 0

        let s:tlist_{fidx}_tag_count = g:tlist_{i}_tag_count
        unlet g:tlist_{i}_tag_count

        let j = 1
        while j <= s:tlist_{fidx}_tag_count
            let s:tlist_{fidx}_tag_{j} = g:tlist_{i}_tag_{j}
            unlet g:tlist_{i}_tag_{j}
            let j = j + 1
        endwhile

        let j = 1
        while j <= s:tlist_{ftype}_count
            let ttype = s:tlist_{ftype}_{j}_name

            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}_count = g:tlist_{i}_{ttype}_count
                unlet g:tlist_{i}_{ttype}_count

                let k = 1
                while k <= s:tlist_{fidx}_{ttype}_count
                    let s:tlist_{fidx}_{ttype}_{k} = g:tlist_{i}_{ttype}_{k}
                    unlet g:tlist_{i}_{ttype}_{k}
                    let k = k + 1
                endwhile
            else
                let s:tlist_{fidx}_{ttype} = ''
                let s:tlist_{fidx}_{ttype}_start = 0
                let s:tlist_{fidx}_{ttype}_count = 0
            endif

            let j = j + 1
        endwhile

        let i = i + 1
    endwhile

    
" Initialize the taglist window
    call s:Tlist_Init_Window()

    
if s:tlist_file_count > 0
        
" Jump to the beginning of the first file
        call cursor(s:tlist_0_start, 1)
    endif
endfunction

" Tlist_Session_Save
" Save a taglist session (information about all the displayed files
" and the tags) into the specified file
function! s:Tlist_Session_Save()
    
if a:0 == 0 || a:1 == ''
        call s:Tlist_Warning_Msg('Usage: TlistSessionSave 
<filename>')
        
return
    endif

    let sessionfile 
= a:1

    
if s:tlist_file_count == 0
        
" There is nothing to save
        call s:Tlist_Warning_Msg('Warning: Taglist is empty. Nothing to save.')
        return
    endif

    if filereadable(sessionfile)
        let ans = input(
"Do you want to overwrite " . sessionfile . " (Y/N)?")
        if ans !=? 'y'
            return
        endif

        echo 
"\n"
    endif

    exe 'redir! > ' . sessionfile

    silent! echo '
" Taglist session file. This file is auto-generated.'
    silent
! echo '" File information'
    silent! echo 'let g:tlist_file_count = ' . s:tlist_file_count

    let i = 0

    while i < s:tlist_file_count
        
" Store information about the file
        silent
! echo 'let g:tlist_' . i . "_filename = '" . 
                                            \ s:tlist_{i}_filename . 
"'"
        silent
! echo 'let g:tlist_' . i . '_sort_type = "' . 
                                                \ s:tlist_{i}_sort_type . '
"'
        silent
! echo 'let g:tlist_' . i . '_filetype = "' . 
                                            \ s:tlist_{i}_filetype . '
"'
        silent
! echo 'let g:tlist_' . i . '_tag_count = ' . 
                                                        \ s:tlist_{i}_tag_count
        
" Store information about all the tags
        let j = 1
        while j <= s:tlist_{i}_tag_count
            let txt = escape(s:tlist_{i}_tag_{j}, '
"\\')
            silent
! echo 'let g:tlist_' . i . '_tag_' . j . ' = "' . txt . '"'
            let j 
= j + 1
        endwhile

        
" Store information about all the tags grouped by their type
        let ftype = s:tlist_{i}_filetype
        let j = 1
        while j <= s:tlist_{ftype}_count
            let ttype = s:tlist_{ftype}_{j}_name
            if s:tlist_{i}_{ttype}_count != 0
                let txt = substitute(s:tlist_{i}_{ttype}, 
"\n""\\\\n""g")
                silent! echo 'let g:tlist_' . i . '_' . ttype . ' = 
"' . 
                                                \ txt . '
"'
                silent! echo 'let g:tlist_' . i . '_' . ttype . '_count = ' . 
                                                     \ s:tlist_{i}_{ttype}_count
                let k = 1
                while k <= s:tlist_{i}_{ttype}_count
                    silent! echo 'let g:tlist_' . i . '_' . ttype . '_' . k . 
                                \ ' = ' . s:tlist_{i}_{ttype}_{k}
                    let k = k + 1
                endwhile
            endif
            let j = j + 1
        endwhile

        silent! echo

        let i = i + 1
    endwhile

    redir END
endfunction


" Define the taglist autocommand to automatically open the taglist window on
" Vim startup
if g:Tlist_Auto_Open
    autocmd VimEnter * nested Tlist
endif

" Define the user commands to manage the taglist window
command
! -nargs=0 Tlist call s:Tlist_Toggle_Window(bufnr('%'))
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('.'))
command
! -nargs=? TlistShowPrototype echo s:Tlist_Get_Tag_Prototype_By_Line(<q-args>)
command
! -nargs=* -complete=file TlistSessionLoad call s:Tlist_Session_Load(<q-args>)
command
! -nargs=* -complete=file TlistSessionSave call s:Tlist_Session_Save(<q-args>)

" Winmanager integration

" Initialization required for integration with winmanager
function! TagList_Start()
    let s:tlist_part_of_winmanager 
= 1

    
if bufname('%') != '__Tag_List__'
        
return
    endif

    
" Get the current filename from the winmanager plugin
    let bufnum = WinManagerGetLastEditedFile()
    if bufnum != -1
        let filename = fnamemodify(bufname(bufnum), ':p')
        let fidx = s:Tlist_Get_File_Index(filename)

        if fidx != -1 && fidx == s:tlist_cur_fidx
            
" If the tags for the buffer is already listed, then no need to do
            
" anything
            return
        endif

        let ftype = getbufvar(bufnum, '&filetype')
    endif

    
" 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()
        let s:tlist_window_initialized 
= 1
    endif

    
" Open the taglist window
    if bufnum != -1
        call s:Tlist_Explore_File(filename, ftype)
    endif
endfunction

function! TagList_IsValid()
    return 0
endfunction

function! TagList_WrapUp()
    return 0
endfunction



参考文献:
  1. http://www.crium.univ-metz.fr/docs/devel/vim/taglist.vim
  2. http://blog.sina.com.cn/u/4946aa22010005w9
  3. http://blog.csdn.net/easwy/archive/2007/03/02/1518902.aspx


只有注册用户登录后才能发表评论。


网站导航: