天天看點

vim+ctags+taglist插件安裝使用vim+ctags+taglist插件安裝使用

From:http://www.blogjava.net/zellux/archive/2007/06/12/123556.html

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('
       

參考文獻:

  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

  , ' ')

    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 '^[^ "  ]. * 參考文獻:

  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

        syntax match TagListTitle ' ^   /S. * 參考文獻:

  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

        syntax match TagListTagScope  '/s/[./{ - /}/] 參考文獻:

  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

         "  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(' 參考文獻:

  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

  )

         else

            let s:tlist_{fidx}_start  =  line(' 參考文獻:

  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

  )  +   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(' 參考文獻:

  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

  , ' ')

    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] == ' 參考文獻:

  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

                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 ]  ==  ' 參考文獻:

  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

        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('.') . '/ 參考文獻:

  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

     "  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('.') . '/ 參考文獻:

  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

    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* 參考文獻:

  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

   || 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 ]  ==  ' 參考文獻:

  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

            let end  =  end  -   1

        endif

        let tagpat  =  '/V/ ^ ' . strpart(mtxt, start, end  -  start) .

                                            / (mtxt[end]  ==  ' 參考文獻:

  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

    ?  '/ 參考文獻:

  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

   : '')

         "  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* 參考文獻:

  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

   || 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插件安裝使用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插件安裝使用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