Chinaunix首页 | 论坛 | 博客
  • 博客访问: 276448
  • 博文数量: 28
  • 博客积分: 690
  • 博客等级: 上士
  • 技术积分: 358
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-25 20:39
文章分类

全部博文(28)

文章存档

2012年(12)

2011年(16)

分类: C/C++

2011-12-08 15:10:42

转载:http://blog.csdn.net/Michael_Mao/archive/2007/09/27/1803516.aspx

    "ctags"是一个独立的程序,绝大多数Unix系统上都会预装这个程序。

    1、使用tags
   
    tag是什么?一个位置。它记录了关于一个标识符在哪里被定义的信息,比如C或C++程序中的一个函数定义。这种tag聚集在一起被放入一个tags文件。这个文件可以让Vim能够从任何位置起跳达到tag所指示的位置-标识符被定义的位置。

    下面的命令可以为当前目录下的所有C程序文件生成对应的tags文件:
        (shell command) ctags *.c


    现在你在Vim中要跳到一个函数的定义(如startlist)就可以用下面的命令:
       (ex command) :tag startlist
这个命令会带你到函数"startlist"的定义处,哪怕它是在另一个文件中。

    CTRL+] 命 令会取当前光标下的word作为tag的名字并直接跳转。这使得在大量C程序中进行探索更容易一些。假设你正看函数"write block",发现它调用了一个叫"write line"的函数,这个函数是干什么的呢?你可以把光标置于"write_line"上,按下CTRL+] 即可。如果"write_line"函数又调用了 "write_ char".你当然又要知道这个函数又是什么功能。同时,置光标于"write_char"上按下CTRL+]。现在你位于函数"write_char" 的定义处。

    ":tags"命令会列出现在你就已经到过哪些tag了:
       (ex command):tags
       #      TO          tag       FROM line          in file/text
       1       1       write_line        8             write_block.c
       2       1       write_char        7             write_line.c

    现在往回走。CTRL+T命 令会跳到你前一次的tag处。在上例中它会带你到调用了"write_char"的"write_line"函数的地方。CTRL+T可以带一个命令记 数, 以此作为往回跳的次数, 你已经向前跳过了,现在正在往回跳,我们再往前跳一次。下面的命令可以直接跳转到当前tag序列的最后:
       (ex command) :tag
你也可以给它一个前辍, 让它向前跳指定的步长. 比如":3tag"。CTRL+T也可以带一个前辍。这些命令可以让你向下深入一个函数调用树(使用CTRL+]), 也可以回溯跳转(使用CTRL+T). 还可以随时用":tags"看你当前的跳转历史记录。

    2、分隔窗口

    ":tag"命令会在当前窗口中载入包含了目标函数定义的文件。但假设你不仅要查看新的函数定义,还要同时保留当前的上下文呢?你可以在":tag"后使用一个分隔窗口命令":split"。Vim还有一个一举两得的命令:
      (ex command) :stag tagname
要分隔当前窗口并跳转到光标下的tag:
      (normal mode command) CTRL+W+]
如果同时还指定了一个命令记数, 它会被当作新开窗口的行高.

    3、多个tags文件

    如果你的源文件位于多个目录下,你可以为每个目录都建一个tags文件。Vim会在使用某个目录下的tags文件进行跳转时只在那个目录下跳转。

    要使用更多tags文件,可以通过改变'tags'选项的设置来引入更多的tags文件。如:
       (ex command) :set tags=./tags, ./../tags, ./*/tags
这 样的设置使Vim可以使用当前目录下的tags文件,上一级目录下的tags文件,以及当前目录下所有层级的子目录下的tags文件。这样可能会引入很多 的tags文件,但还有可能不敷其用。比如说你正在编辑"~/proj/src"下的一个文件,但又想使用"~/proj/sub/tags"作为 tags文件。对这种Vim情况提供了一种深度搜索目录的形式。如下:(ex command) :set tags=~/proj/**/tags

    4、单个tags文件

    Vim在搜索众多的tags文件时,你可能会听到你的硬盘在咔嗒咔嗒拼命地叫。显然这会降低速度。如果这样还不如花点时间生成一个大一点的tags文件。这需要一个功能丰富的ctags程序,比如上面提到的那个。它有一个参数可以搜索整个目录树:
       (shell command)cd ~/proj
        ctags -R
    用一个功能更强的ctags的好处是它能处理多种类型的文件。不光是C和C++源程序,也能对付Eiffel或者是Vim脚本。你可以参考ctags程序的文件调整自己的需要。现在你只要告诉Vim你那一个tags文件在哪就行了:
        (ex command) :set tags=~/proj/tags

    5、同名tag

    当一个函数被多次重载(或者几个类里都定义了一些同名的函数),":tag"命令会跳转到第一个符合条件的。如果当前文件中就有一个匹配的,那又会优先使用它。当然还得有办法跳转到其它符合条件的tag去:
      (ex command) :tnext
重复使用这个命令可以发现其余的同名tag。如果实在太多,还可以用下面的命令从中直接选取一个:
      (ex command) :tselect tagname
Vim会提供给你一个选择列表,例如:(Display)

#     pri     kind     tag               file
1      F        f      mch_init     os_amiga.c
                        mch_init()
2      F        f      mch_init     os_mac.c
                        mch_init()
3      F        f      mch_init     os_msdos.c
                        mch_init(void)
4      F        f      mch_init     os_riscos.c
                        mch_init()
Enter nr of choice ( to abort):

   现在你只需键入相应的数字(位于第一栏的)。 其它栏中的信息是为了帮你作出决策的。在多个匹配的tag之间移动,可以使用下面这些命令:
       (ex command):tfirst             go to first match
                   :[count]tprevious   go to [count] previous match
                   :[count]tnext       go to [count] next match
                   :tlast              go to last match
如果没有指定[count],默认是1。

    6、tag的名字

    命令补齐真是避免键入一个长tag名的好办法。只要输入开头的几个字符然后按下制表符:
       (ex command) :tag write_
Vim 会为你补全第一个符合的tag名。如果还不合你意,接着按制表符直到找到你要的。有时候你只记得一个tag名的片段,或者有几个tag开头相同。这里你可以用一个模式匹配来告诉Vim你要找的tag。

    假设你想跳转到一个包含"block"的tag。首先键入命令:(ex command) :tag /block。现在使用命令补齐:按。Vim会找到所有包含"block"的tag并先提供给你第一个符合的。"/"告诉Vim下 面的名字不是一五一十的tag名,而是一个搜索模式。通常的搜索技巧都可以用在这里。比如你有一个tag以"write "开始:(ex command) :tselect / ^write_,"^"表示这个tag以"write_"开始。不然在半中间出现write的tag也会被搜索到。同样"$"可以用于告诉Vim要查找的 tag如何结束。

    7、tags的浏览器

    CTRL+]可以直接跳转到以当前光标下的word为tag名的地方去,所以可以在一个tag列表中使用它。下面是一个例子。首先建立一个标识符的列表(这需要一个好的ctags):
      (shell command) ctags --c-types=f -f functions *.c

    现在直接启动Vim, 以一个垂直分隔窗口的编辑命令打开生成的文件:
       (shell command) vim:vsplit functions
    这个窗口中包含所有函数名的列表。可能会有很多内容,但是你可以暂时忽略它。用一个":setlocal ts=99"命令清理一下显示。在该窗口中,定义这样的一个映射:
        (ex command):nnoremap 0yew:tag "
    现在把光标移到你想要查看其定义的函数名上,按下回车键,Vim就会在另一个窗口中打开相应的文件并定位到到该函数的定义上。

    8、其它相关主题

    设置'ignorecase'也可以让tag名的处理忽略掉大小写。'tagsearch'选项告诉Vim当前参考的tags文件是否是排序过的。默认情 况假设该文件是排序过的,这会使tag的搜索快一些,但如果tag文件实际上没有排序就会在搜索时漏掉一些tag。

    'taglength'告诉Vim一个tag名字中有效部分的字符个数。例:
#include
int very_long_variable_1;
int very_long_variable_2;
int very_long_variable_3;
int very_long_variable_4;
int main()
{
    very_long_variable_4 = very_long_variable_1 *
    very_long_variable_2;
}

    对于上面这段代码, 4个变量长度都为20, 如果将'taglength'设为10, 则:
       (ex command):tag very_long_variable_4
会匹配到4个tag,而不是1个,光标停留在very_long_variable_1所在行上,因为被搜索的tag部分只有前面的10个字符: "very_long_",相应的显示是(是gvim中文版的真正显示,不是翻译的):
      (Display)找到tag: 1/4 或更多

cscope使用

打开vim的配置文件:sudo gedit /etc/vim/vimrc;然后在该文件下添加如下代码:
if filereadable("cscope.out")
    cs add cscope.out
endif

这样每次打开vim就可以直接使用cscope了,或者执行如下命令

:cs add cscope.out
在源码目录下通过命令make cscope生成索引文件。

在vim命令行下执行: :cs help cscope commands: add : Add a new database (Usage: add file|dir [pre-path] [flags]) find : Query for a pattern (Usage: find c|d|e|f|g|i|s|t name) c: Find functions calling this function d: Find functions called by this function e: Find this egrep pattern f: Find this file g: Find this definition i: Find files #including this file s: Find this C symbol t: Find assignments to help : Show this message (Usage: help) kill : Kill a connection (Usage: kill #) reset: Reinit all connections (Usage: reset) show : Show connections (Usage: show)
s: 查找C语言符号,即查找函数名、宏、枚举值等出现的地方
g: 查找函数、宏、枚举等定义的位置,类似ctags所提供的功能
d: 查找本函数调用的函数
c: 查找调用本函数的函数
t: 查找指定的字符串
e: 查找egrep模式,相当于egrep功能,但查找速度快多了
f: 查找并打开文件,类似vim的find功能
i: 查找包含本文件的文



Taglist 安装使用


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

: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
  • 系统中装了工具,并且taglist plugin能够找到此工具(因为taglist需要调用它来生成tag文件)
  • 你的vim支持system()调用

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

现在我们到下载最新版本的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窗口中,可以使用下面的快捷键:

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

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

map :TlistToggle

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

taglist 的配置


  为了让taglist窗口更加适合不同人的开发,可以在vim的配置文件 ~/.vimrc 中进行一些配置

  1. Tlist_GainFocus_On_ToggleOpen :        #为1则使用TlistToggle打开标签列表窗口后会获焦点至于标签列表窗口;为0则taglist打开后焦点仍保持在代码窗口
  2. Tlist_Auto_Open                       # 为1则Vim启动后自动打开标签列表窗口
  3. Tlist_Close_On_Select :               # 选择标签或文件后是否自动关闭标签列表窗口
  4. Tlist_Exit_OnlyWindow :               #Vim当前仅打开标签列表窗口时,是否自动退出Vim
  5. Tlist_Use_SingleClick :               #是否将默认双击标答打开定义的方式更改为单击后打开标签
  6. Tlist_Auto_Highlight_Tag :            #是否高亮显示当前标签。命令":TlistHighlightTag"也可达到同样效果
  7. Tlist_Highlight_Tag_On_BufEnter :     # 默认情况下,Vim打开/切换至一个新的缓冲区/文件后,标签列表窗口会自动将当前代码窗口对应的标签高亮显示。 TlistHighlight_Tag_On_BufEnter置为0可禁止以上行为
  8. Tlist_Process_File_Always :           #为1则即使标签列表窗口未打开,taglist仍然会在后台处理vim所打开文件的标签
  9. Tlist_Auto_Update :                   #打开/禁止taglist在打开新文件或修改文件后自动更新标签。禁止自动更新后,taglist仅在使 用:TlistUpdate,:TlistAddFiles,或:TlistAddFilesRecursive命令后更新标签
  10. Tlist_File_Fold_Auto_Close :          #自动关闭标签列表窗口中非激活文件/缓冲区所在文档标签树,仅显示当前缓冲区标签树
  11. Tlist_Sort_Type :                     #标签排序依据,可以为"name"(按标签名排序)或"order"(按标签在文件中出现的顺序,默认值)
  12. Tlist_Use_Horiz_Window :              #标签列表窗口使用水平分割样式
  13. Tlist_Use_Right_Window :              #标签列表窗口显示在右侧(使用垂直分割样式时)
  14. Tlist_WinWidth :                      #设定水平分割时标签列表窗口的宽度
  15. Tlist_WinHeight :                     #设定垂直分割时标签列表窗口的高度
  16. Tlist_Inc_Winwidth :                  #显示标签列表窗口时允许/禁止扩展Vim窗口宽度
  17. Tlist_Compact_Format :                #减少标签列表窗口中的空白行
  18. Tlist_Enable_Fold_Column :            #是否不显示Vim目录列
  19. Tlist_Display_Prototype :             #是否在标签列表窗口用标签原型替代标签名
  20. Tlist_Display_Tag_Scope :             #在标签名后是否显示标签有效范围
  21. Tlist_Show_Menu :                     #在图型界面Vim中,是否以下拉菜单方式显示当前文件中的标签
  22. Tlist_Max_Submenu_Item :              #子菜单项上限值。如子菜单项超出此上限将会被分隔到多个子菜单中。缺省值为25
  23. Tlist_Max_Tag_Length :                #标签菜单中标签长度上限

阅读(2216) | 评论(3) | 转发(1) |
0

上一篇:谁说C语言很简单?

下一篇:Vim 复制 粘贴

给主人留下些什么吧!~~

泥亚鳅2011-12-14 02:09:25

匿名: 恩,谢谢提醒~.....
哈哈,好多了现在!

2011-12-10 10:36:50

泥亚鳅: 文章好挤啊,建议重新一下版~~.....
恩,谢谢提醒~

泥亚鳅2011-12-09 00:57:37

文章好挤啊,建议重新一下版~~