天天看點

vim+ctags+taglist插件安裝使用

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

Posted on 2007-06-12 11:38 ZelluX 閱讀(1741) 評論(0)   編輯   收藏 所屬分類: Linux

vim+ctags+taglist插件安裝使用

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 
   1
   , 
   2003
   

   "
   

   "
    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 
   +
    
   1
   , 
   0
   , 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(
   -
   1
   , 
   1
   )
   <
   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(
   -
   1
   , 
   1
   )
   <
   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 
   +
    
   1
   , 
   1
   , 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 
   =
    ' 
   -
   f 
   -
    
   --
   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 
   95
   , 
   if
    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(
        
vim+ctags+taglist插件安裝使用
)      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(
vim+ctags+taglist插件安裝使用
)      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