vi/vim使用进阶: 使用taglist插件

<< 返回vim使用进阶: 目录

本节所用命令的帮助入口:

:help helptags
:help taglist.txt 

上篇文章介绍了在vim中如何使用tag文件,本文主要介绍如何使用taglist插件(plugin)。

想必用过Source Insight的人都记得这样一个功能:SI能够把当前文件中的宏、全局变量、函数等tag显示在Symbol窗口,用鼠标点上述tag,就跳到该tag定义的位置;可以按字母序、该tag所属的类或scope,以及该tag在文件中出现的位置进行排序;如果切换到另外一个文件,Symbol窗口更新显示这个文件中的tag。

在vim中的taglist插件所实现的就是上述类似的功能,有些功能比SI弱,有些功能比SI更强。而且,taglist插件还在不断完善中!

要使用taglist plugin,必须满足:

  • 打开vim的文件类型自动检测功能:filetype on
  • 系统中装了Exuberant ctags工具,并且taglist plugin能够找到此工具(因为taglist需要调用它来生成tag文件)
  • 你的vim支持system()调用

在文章vimrc初步中,我们使用了vim自带的示例vimrc,这个vimrc中已经打开了文件类型检测功能;在上篇文章中,我们也已用到了Exuberant ctags;system()调用在一般的vim版本都会支持(suse Linux发行版中出于安全考虑,关闭了此功能),所以我们已经满足了这三个条件。

现在我们到http://www.vim.org/scripts/script.php?script_id=273下载最新版本的taglist plugin,目前版本是4.3。

下载后,把该文件在~/.vim/目录中解压缩,这会在你的~/.vim/plugin和~/.vim/doc目录中各放入一个文件:

plugin/taglist.vim – taglist插件
doc/taglist.txt    - taglist帮助文件 

注:windows用户需要把这个插件解压在你的$vim/vimfiles或$HOME/vimfiles目录。

使用下面的命令生成帮助标签(下面的操作在vim中进行):

:helptags ~/.vim/doc 

生成帮助标签后,你就可以用下面的命令查看taglist的帮助了:

:help taglist.txt 

Taglist提供了相当多的功能,我的vimrc中这样配置:

""""""""""""""""""""""""""""""
" Tag list (ctags)
""""""""""""""""""""""""""""""
if MySys() == "windows"                "设定windows系统中ctags程序的位置
let Tlist_Ctags_Cmd = 'ctags'
elseif MySys() == "linux"              "设定linux系统中ctags程序的位置
let Tlist_Ctags_Cmd = '/usr/bin/ctags'
endif
let Tlist_Show_One_File = 1            "不同时显示多个文件的tag,只显示当前文件的
let Tlist_Exit_OnlyWindow = 1          "如果taglist窗口是最后一个窗口,则退出vim
let Tlist_Use_Right_Window = 1         "在右侧窗口中显示taglist窗口 

这样配置后,当你输入”:TlistOpen“时,显示如下窗口:

在屏幕右侧出现的就是taglist窗口,你从中可以看到在main.c文件中定义的所有tag:宏、定义、变量、函数等;你也可以双击某个tag,跳到该tag定义的位置;你还可以把某一类的tag折叠起来(使用了vim的折行功能),方便查看,就像上图中macro和variable那样。更多的功能,请查看taglist的帮助页,本文也会介绍一些常用功能。

下面介绍常用的taglist配置选项,你可以根据自己的习惯进行配置:

  • Tlist_Ctags_Cmd选项用于指定你的Exuberant ctags程序的位置,如果它没在你PATH变量所定义的路径中,需要使用此选项设置一下;
  • 如果你不想同时显示多个文件中的tag,设置Tlist_Show_One_File为1。缺省为显示多个文件中的tag;
  • 设置Tlist_Sort_Type为”name“可以使taglist以tag名字进行排序,缺省是按tag在文件中出现的顺序进行排序。按tag出现的范围(即所属的namespace或class)排序,已经加入taglist的TODO List,但尚未支持;
  • 如果你在想taglist窗口是最后一个窗口时退出vim,设置Tlist_Exit_OnlyWindow为1;
  • 如果你想taglist窗口出现在右侧,设置Tlist_Use_Right_Window为1。缺省显示在左侧。
  • 在gvim中,如果你想显示taglist菜单,设置Tlist_Show_Menu为1。你可以使用Tlist_Max_Submenu_ItemsTlist_Max_Tag_Length来控制菜单条目数和所显示tag名字的长度;
  • 缺省情况下,在双击一个tag时,才会跳到该tag定义的位置,如果你想单击tag就跳转,设置Tlist_Use_SingleClick为1;
  • 如果你想在启动vim后,自动打开taglist窗口,设置Tlist_Auto_Open为1;
  • 如果你希望在选择了tag后自动关闭taglist窗口,设置Tlist_Close_On_Select为1;
  • 当同时显示多个文件中的tag时,设置Tlist_File_Fold_Auto_Close为1,可使taglist只显示当前文件tag,其它文件的tag都被折叠起来。
  • 在使用:TlistToggle打开taglist窗口时,如果希望输入焦点在taglist窗口中,设置Tlist_GainFocus_On_ToggleOpen为1;
  • 如果希望taglist始终解析文件中的tag,不管taglist窗口有没有打开,设置Tlist_Process_File_Always为1;
  • Tlist_WinHeightTlist_WinWidth可以设置taglist窗口的高度和宽度。Tlist_Use_Horiz_Window为1设置taglist窗口横向显示;

在taglist窗口中,可以使用下面的快捷键:

<CR>          跳到光标下tag所定义的位置,用鼠标双击此tag功能也一样
o             在一个新打开的窗口中显示光标下tag
<Space>       显示光标下tag的原型定义
u             更新taglist窗口中的tag
s             更改排序方式,在按名字排序和按出现顺序排序间切换
x             taglist窗口放大和缩小,方便查看较长的tag
+             打开一个折叠,同zo
-             将tag折叠起来,同zc
*             打开所有的折叠,同zR
=             将所有tag折叠起来,同zM
[[            跳到前一个文件
]]            跳到后一个文件
q             关闭taglist窗口
<F1>          显示帮助 

可以用”:TlistOpen“打开taglist窗口,用”:TlistClose“关闭taglist窗口。或者使用”:TlistToggle“在打开和关闭间切换。在我的vimrc中定义了下面的映射,使用<F9>键就可以打开/关闭taglist窗口:

map <silent> <F9> :TlistToggle<cr> 

Taglist插件还提供了很多命令,你甚至可以用这些命令创建一个taglist的会话,然后在下次进入vim时加载此会话。

Taglist插件还可以与winmanager插件协同使用,这将在下篇文章中介绍。

[参考文档]

<< 返回vim使用进阶: 目录

“vi/vim使用进阶: 使用taglist插件”的40个回复

    1. 根据Taglist的帮助文档,Taglist会检查文件的修改时间,如果文件修改了,它会自动刷新Tag。你也可以在Taglist窗口中用u命令来手动刷新,或者使用EX命令”:TlistUpdate”进行刷新。

  1. 你好,请问如果我想在taglist中查看另外一个文件个tag该如何设置。。。比如说我打开的是main.c,然后我想查看ADC.c中的tag。。。。
    谢谢

  2. 博主你好,我按照你的教程进行配置,taglist也可以正常使用,但是为什么它左边的边框那么粗呢?
    之后我再看你的配图,发现你图中taglist窗口左边的边框也是很粗的(只是因为配色的原因没我的那么明显)。
    我想有没有可能是因为开启了显示行号的功能造成的,于是去掉行号显示(:set nonumber),主窗口左边的边框变细了,但taglist窗口的边框还是那么粗。

    博主你知道如何让taglist窗口左边的边框变细吗?求教!

  3. @Lux
    看你的错误,应该是你的vimrc中没有定义MySys()这个函数

    vim的文档非常全面,你可以在vim中输入”:help XXX”来查看关于XXX的帮助文件,例如,对你上面的错误,你可以用:

    :help E124
    :help E117
    :help E15

  4. 前辈您好,我是一个刚刚开始接触vim的新手
    看了您的vimbolg,有些疑问
    我照着步骤执行,将代码写入vimrc后,
    终端打开时提示我一下错误

    ➜ ~ mvim ~/.vimrc
    ➜ ~ Error detected while processing /Users/risyran/.vimrc:
    line 38:
    E117: Unknown function: MySys
    E15: Invalid expression: MySys()==”windows”^I^I”设定windows系统中的ctags程序的位置”

    因为我对很多东西不理解,首先是这些函数方法,不晓得为什么直接就写,有引入和声明的概念么?这些我不太清楚,所以照前辈的代码原封不动的copy上去,提示如上错误,进入vim后也能执行TlistOpen,但是目前并没有打开某程序文件,所以不清楚效果,但是您能否抽空解答我这菜鸟的这些小小疑问呢?
    首先是这些方法哪里可以看到?如何知道它们的用处?是否有文档?以及出了的这个错误如何解决?

    如果您能指点几下就太开心了

  5. @newer
    buf explorer应该是自动更新的,每打开一个缓冲区,它都能自动更新。

    如果Taglist不自动更新新增加的函数,你可以在Taglist窗口里使用”u”命令刷新一下就行了。

  6. Taglist的tags列表不自动更新??
    编辑文件,保存文件后要切换当前文件窗口或者重新加载文件才Tlist列表才刷新

    bufexplorer同样问题。好像ctags生成的tag文件已更新。当时vim窗口没有自动触发更新

    问如何设置能让Taglist和bufexplorer自动更新?

  7. 博主,您好,近期在读您的文章,受益匪浅,现在有个问题请释疑,非常感谢。
    :现在遇到一个很困惑的问题就是使用ctags时,如果要跳转到另一个文件的话,就需要保存当前编辑的文件,很烦,请问有没有办法不保存,直接跳转?

  8. @Easwy
    谢谢回复,
    第二个问题是指:如何在当前工作目录下的所有文件中查询某个字符串,也就是查询文件中的内容。因为第一个问题,导致没有办法准确定位次级目录下的文件中某个函数被定义的地方,所以我想通过搜索当前工作目录下所有文件的办法来做,就像ECLIPSE中的文件搜索一样,不知道VIM可以办到不?
    第一个问题,没有研究一下,谢谢,现在电脑还没有安装VIM的环境了,最近想从ECLIPSE转到VIM下来写写程序,呵呵,这里是一个好地方。

  9. 还有一个问题就是查当前工作路径下所有文件中的每一个函数,特别是在TAGS无效的情况下,这个很重要,不知道VIM可以做到不?

  10. 在用TAG的时候,遇到一个问题,就是我在根目录下生成的TAGS,当进入下级目录,再在下级目录下,按 ctrl+]找不到函数定义的地方,但是把工作路径设会到根目录,就可以找到。通过SET PATH+=根目录也效,有谁可以指点一下不?

  11. buaalevin :
    又看了一下发现不是黑底色的原因
    在Konsole的bash下不能在vim中用taglist啊?一用bash就黑屏

    这个问题也困扰我很久了,只是用konsole习惯了~

  12. 我在Fedora10下按照你说的步骤配置好了,在vim里tag正常,但是taglist用不了,在vim中输入:TlistOpen或者TlistToggle,有Tlist的小窗口出来,但是bash一片黑,感觉使用东西的,因为在Tlist的小窗口里乱按回车的话会出来可能是tag对应的代码,但是bash上只有@和~在每行开始处显示,然后别的什么都没有。:q退出的vim话也是什么都不显示,bash全黑.楼主能告诉怎么处理吗?

  13. (以下为CSDN评论的转帖)

    #muzuiget 发表于2007-06-03 18:13:28 IP: 61.140.26.*
    1.windwos xp下,从sourceforge.net下载啦点ctags是zip的,解压后一大堆文件,没有安装程序,安了taglist后,启动vim,弹出个消息框说找不到在path在不到ctags,把目录加进path去后,ok。如果我不想用环境变量定位目录(因为我想把vim和相关工具打包好在别的电脑用),跟据楼主写的这篇文,提到在.vimrc中写一条
    let Tlist_Ctags_Cmd = ‘ctags’
    比如ctags目录是的d:\ctags,我试了好几种写法都不行,还是会弹出那个对话框,不知道应该怎么写才对?麻烦Easwy指教一下。
    2.再问一个火星问题,taglist的Ex命令中有“Tlist”命令,也是打开和关闭窗口的,不知道这个命令和TlistTogg有什么分别,我在帮助文件中找不到说明。

    ps:
    在“Taglist提供了相当多的功能,我的vimrc中这样配置:”下边的代码,第二句注释应该是在l“inux系统下”吧?

    #easwy 发表于2007-06-04 13:45:47 IP: 213.70.90.*
    试一下下面的写法(目录改成你自己的,如果目录含空格使用”\”字符转义):
    let Tlist_Ctags_Cmd = ‘e:/ctags’

    Tlist命令是旧版本的taglist中的命令,现在改成TlistToggle了,二者是一样的

    注释错误已改正,多谢 :)

    #muzuiget 发表于2007-06-07 15:12:16 IP: 218.20.194.*
    试了n次终于成功,开始我在_gvimrc文件设置这条语句,死活不行,后来写在_vimrc下才成功,莫非vim的插件比_gvimrc更早执行?同时要带上ctags.exe程序名才行(认真看了帮助文件才发现),如果目录有空格,就要加上双引号,郁闷了我半天。

  14. (以下为CSDN评论的转帖)

    #flyincosmic 发表于2007-05-06 20:46:54 IP: 220.207.37.*
    就是如你所介绍的方法
    ctags -R dir啊
    代码的错误该和这个无关的,而且代码本身是可以编译的
    找不到tag就是上面所说的,tag一个结构找到了两个结果,一个是定义, struct Freq_Edge,一个是构造, struct:Freq_Edge,但是选择构造这个结果就找不到tag了,
    我刚刚开始x学着用vim写代码,这是以前写的,拿来作试验的,不存在更新的问题

    有些定义就根本定位不到了,不确定是哪种,就是结构体,函数,变量,typedef,都有能定位的不能定位的

    #flyincosmic 发表于2007-05-06 23:15:36 IP: 220.192.41.*
    看来是我的tags有问题,Exuberant tags 5.6应该是没问题的,但是ctags -R dir 生成的只是一个338字节的只包含ctags站点信息的空tag
    但是3号却是生成了15k的tags,不知怎么回事

  15. (以下为CSDN评论的转帖)

    #mikeshi 发表于2007-03-05 19:38:37 IP: 192.14.13.*
    你好,最近也正想写一些关于用vi编程的文章,没想到你已经先走一步了,呵呵,以后要好好想你学习,提高vi水平

    2007-03-07 09:20:11作者回复
    有空大家多多交流!我们争取多做一些工作,使VIM这样的好工具能为更多人所用

    #flyincosmic 发表于2007-05-03 21:42:31 IP: 220.192.43.*
    有些tag明明有的,taglist也显示出了,但就是无法定位到定义处,不管是tag {tag}还是在taglist window内回车都不行

    有些匹配到的结果会告诉找不到tag,类别FCf,最后一个F不知是什么意思,
    比如 struct Freq_Edge,显示的结果是

    1 F C f Freq_Edge \AssocMap.h
    struct:Freq_Edge (实际上是没有这个冒号的,但不知vim认为应该这样显示) Freq_Edge(arg1, arg2, arg3)

    2 F C s Freq_Edge \AssocMap.h
    struct Freq_Edge

    有些匹配到的结果就可以全部显示

    类别是 F C t, t也是在帮助里没有的

    #easwy 发表于2007-05-04 12:15:33 IP: 219.133.160.*
    上面显示结果中的f、s是该标签的类型,f表示此标签是函数,s表示此标签是结构,在命令行下执行ctags –list-kinds,可以了解这些标记的含义

    从上面看的结果看,似乎是你的tags文件有问题,你是怎么生成标签文件的?不能确定是不是和你的源代码有关。

    找不到tag的情况能不能给详细说一下?
    如果你更改了源文件而没有更新tag文件的话,新加入的tag就会找不到。不过taglist是可以实时更新的,应该不会有这种情况。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注