Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1212068
  • 博文数量: 261
  • 博客积分: 4196
  • 博客等级: 上校
  • 技术积分: 3410
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-17 17:05
文章分类

全部博文(261)

文章存档

2018年(1)

2017年(22)

2016年(2)

2015年(8)

2014年(27)

2013年(40)

2012年(161)

分类: LINUX

2012-11-20 11:14:20

     当工程项目相对较大/复杂时,源文件常常分类别/层次存放在不同子目中。这种情况下,可以在工程根路径下,使用"-R"选项使ctags遍历各级子文件夹,为工程生成单一的标签文件。一般地,工程的标签文件存放于工程根文件夹之下。通过对vim配置文件中(一般为~/.vimrc)"tags"项目的设置,我们可以控制Vim查找标签文件的位置和顺序。

Vim允许指定从当前路径开始,逐级向上查找文件的方式。因此一种更好的方法是

  1. set tags=./tags;,~/.vim/tags/linux/ctags/tags  

以上配置指定Vim从当前打开文件所在文件夹下开始,并逐级向自动查找tags文件,直至找到标签或到达根路径('/')。(当然还有一另一个固定的标签文件~/.vim/tags/linux/ctags/tags)

以上就是设置多个tags标签的基本模式,可套用。

 自动更新标签文件


        Vim中的au[tocmd]命令,可以设定用事件来触发执行用户指定命令。此外,Vim也支持脚本的使用。结合Vim脚本和au命令,可以完成代码修改后自动更新标签文件定义的功能。

如果代码标签文件位置固定(~/.vim/tags/usr/ctags/tags),则可以在Vim配置中进行如下设置:

  1. au BufWritePost *.cpp,*.h,*.c,*.def call system("ctags --tag-relative -a  -o ~/.vim/tags/usr/ctags/tags --extra=+q " . expand("%:p")) 

以上配置当"*.cpp,*.h,*.c,*.def"文件在完成保存操作后(BufWritePost),自动调用系统命令(system)去执 行ctags命令,并指定ctags以相对路径("--tag-relative")、追加("-a")方式将当前文件(expand("%:p"))的 标签生成至目标文件(~/.vim/tags/usr/ctags/tags)中。


如果我们使用了上面将标签文件存放在项目根路径下、Vim从当前打开文件所在路径开始逐级向上查找标签文件的方式,则需要额外定位所使用标签文件所在位置。

  1. function RegenTag()  
  2.     let tagfile = findfile("tags"".;")  
  3.   
  4.     if strlen(tagfile) == 0  
  5.         let tagfile = "./tags"  
  6.     endif  
  7.   
  8.     call system("ctags --tag-relative -a --extra=+q -o " .tagfile ." " .expand("%:p"))  
  9. endfunction  
  10.   
  11. au BufWritePost *.cpp,*.h,*.c,*.def call RegenTag() 

     RegenTag()函数中,我们使用了Vim内置函数findfile()从当前路径开始逐级向上去查找是否存在tags文件。如果找到,则将当 前文件的标签定向到此文件;如未找到,则在当前打开文件所在文件夹下新建标签文件tagsRegenTag() "*.cpp,*.h,*.c,*.def"类型文件的保存完成事件自动触发。

  完整配置

最终,Vim配置文件中,tags相关设置如下:

  1. set tags=./tags;,~/.vim/tags/linux/ctags/tags  
  2.   
  3. function RegenTag()  
  4.     let tagfile = findfile("tags"".;")  
  5.   
  6.     if strlen(tagfile) == 0  
  7.         let tagfile = "./tags"  
  8.     endif  
  9.   
  10.     call system("ctags --tag-relative -a --extra=+q -o " .tagfile ." " .expand("%:p"))  
  11. endfunction  
  12.   
  13. au BufWritePost *.cpp,*.h,*.c,*.def call RegenTag() 

最终我自己的机器上的配置为;


"让vim去自动搜索并加载标签文件
set tags=./tags;
"自动向上20层寻找标签文件的目录
function RegenTag() 
    let i = 0
      while i < 20
        if filereadable("cscope.out")
          let db = getcwd()
          "echo db
          let $CSCOPE_DB = db
          silent! execute "!vimbuildproject ./"
          let i = 25
        else
          cd ..
          let i += 1
       endif
     endwhile
endfunction
 
"设置自动关联,保存C++,头文件,C文件的时候调用 RegenTag()
au BufWritePost,FileWritePost *.cpp,*.h,*.c,*.def call RegenTag()


 cscpoe设置

    将cscope_maps.vim 插件做下修改,让 vim 自動尋找正確的 cscope 產生出來的 CSCOPE_DB(通常為 cscope.out ),它只会沿着当前目录向上找,找20层为止。


一,cscope_maps.vim 设置

 這邊預設的目錄深度為 20 層,所以如果你的 source code 的目錄深度大於 20 請自行修正 i 的值

if has("cscope")

......

 

" add the database pointed to by environment variable

 

" Search database for each project, you can switch different projects easily, :)

 

let i = 1

  while i < 20

    if filereadable("cscope.out")

      let db = getcwd() . "/cscope.out"

      "echo db

      let $CSCOPE_DB = db

      cs add $CSCOPE_DB

      let i = 20

    else

      cd ..

    let i += 1

  endif

endwhile

 

" show msg when any other cscope db added


 二、Create goproj.sh and put it in ~/bin

這是為了方便建立 cscope.out CSCOPE_DB)而寫的 goproj.sh,內容如下,為了方便起見可放在 ~/bin 下面。

Content of goproj.sh

      

#!/bin/bash

CSCOPE_FILE=cscope.out

if [ -n "$1" ]; then

  echo "Source code directory: " $1

  echo "Create file map : " $CSCOPE_FILE

  find $1 -name "*.h" -o -name "*.c" -o -name "*.cpp" > $CSCOPE_FILE

  cscope -bkq -i $CSCOPE_FILE

  # cscope -Rbkq

  ctags -R

else

  echo "Please key-in path of project"

fi

 

 使用範例 kernel source

 # tar zxvf kernel-2.6.29.tar.gz

# cd kernel-2.6.29

# goproj.sh `pwd`

# vim xxx.c



[ Ctrl + \ + s ] : 搜尋游標上的 function 哪邊參考到

[ Ctrl + \ + c ] : 搜尋游標上的 function 哪邊呼叫到

[ Ctrl + \ + g ] : 搜尋游標上的 function 是在哪邊定義的

 [ Ctrl + \ + t ] : 跳回下一個位置

[ Ctrl + \ + o ] : 跳回上一個位置

 另外由於 cscope_maps.vim 中有定義 Ctrl + ] 的作用會取代原本 TAG 裡面的定義所以如果不喜歡的話可以把 cscope_maps.vim 中的這行 set cscopetag 移除


 参考

以上配置/脚本,更详细的信息可参考Vim帮助

:help function
:help script
:help tags
:help autocmd


阅读(1660) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~