vim + cscope/ctags/minibuf 查看分析代码

2024-04-28 02:18

本文主要是介绍vim + cscope/ctags/minibuf 查看分析代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用vim + cscope/ctags,就能够实现Source Insight的功能,可以很方便地查看分析源代码。


关键词: vim, cscope, ctags, tags


1. 查看vim是否支持cscope
    $ vim --version | grep cscope


2. 编译支持cscope的VIM(--enable-cscope)
    # USE="bash-completion cscope nls perl python -acl -gpm -minimal -ruby -vim-pager -vim-with-x" emerge vim
    # emerge -av dev-util/cscope
    # emerge -av dev-util/ctags
    $ which cscope
    $ which ctags


3. 查看帮助
    $ man cscope
    $ man ctags
    :help cscope (vim command)
    参考[1]  http://vimcdoc.sourceforge.net/doc/if_cscop.html


4. 使用cscope[2]
    当前目录有main.c,其中调用了cstest.c中的print(),此函数在cstest.h中进行了声明。
    使用下面的命令生成代码的符号索引文件:
    $ cscope -Rbkq
    这个命令会生成三个文件:cscope.out, cscope.in.out, cscope.po.out。

    其中cscope.out是基本的符号索引,后两个文件是使用"-q"选项生成的,可以加快cscope的索引速度。上面命令的参数含义如下:
    -R: 在生成索引文件时,搜索子目录树中的代码
    -b: 只生成索引文件,不进入cscope的界面
    -k: 在生成索引文件时,不搜索/usr/include目录
    -q: 生成cscope.in.out和cscope.po.out文件,加快cscope的索引速度
    -i: 如果保存文件列表的文件名不是cscope.files时,需要加此选项告诉cscope到哪儿去找源文件列表。可以使用"-",表示由标准输入获得文件列表。
    -I dir: 在-I选项指出的目录中查找头文件
    -u: 扫描所有文件,重新生成交叉索引文件
    -C: 在搜索时忽略大小写
    -P path: 在以相对路径表示的文件前加上的path,这样,你不用切换到你数据库文件所在的目录也可以使用它了。
    

    在缺省情况下,cscope在生成数据库后就会进入它自己的查询界面,一般不用这个界面,所以使用了"-b"选项。如果已经进入了这个界面,按CTRL-D退出。

    接下来可以在vim里浏览代码了
    $ vim main.c
    在vim里命令状态下添加符号索引库
    : cscope add cscope.out
    然后可以查看相应的函数定义或文件,ctrl+t返回。
    : cscope find g print
    : cscope find f cstest.h
    
    #注意# 所生成的cscope.out和tags文件要在打开VIM所在的文件夹,否则VIM无法找到相关符号信息。


5. 创建相应的快捷键
    将以下内容添加到~/.vimrc中,vim会自动加载当前目录下的符号索引cscope.out,可以使用ctrl+t、ctrl+]等。

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" cscope setting

if has("cscope")
   set csprg=/usr/bin/cscope              "指定用来执行 cscope 的命令
   set csto=1                             "先搜索tags标签文件,再搜索cscope数据库
   set cst                                "使用|:cstag|(:cs find g),而不是缺省的:tag
   set nocsverb                           "不显示添加数据库是否成功
   " add any database in current directory
   if filereadable("cscope.out")
      cs add cscope.out                   "添加cscope数据库
   endif
   set csverb                             "显示添加成功与否
endif

nmap s :cs find s =expand("")
nmap g :cs find g =expand("")
nmap c :cs find c =expand("")
nmap t :cs find t =expand("")
nmap e :cs find e =expand("")
nmap f :cs find f =expand("")
nmap i :cs find i ^=expand("")$
nmap d :cs find d =expand("")
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

    其中g是先同时按ctrl+@键,之后再按一个g。功能就是查看当前光标所在符号的定义。


6. vim阅读代码
    添加cscope符号索引数据库后,可以调用"cscope find"命令进行查找,vim支持8种cscope的查询功能。如在代码中查找调用work()函数的函数,可以在vim命令状态下输入":cs find c work",回车即可。还可以进行字符串查找,它会对双引号或单引号括起来的内容查找。还可以输入一个正则表达式,这类似于egrep程序的功能。
    :cs help (vim command下查询)

    s: 查找C语言符号,即查找函数名、宏、枚举值等出现的地方
    g: 查找函数、宏、枚举等定义的位置,类似ctags所提供的功能
    d: 查找本函数调用的函数
    c: 查找调用本函数的函数
    t: 查找指定的字符串
    e: 查找egrep模式,相当于egrep功能,但查找速度快多了
    f: 查找并打开文件,类似vim的find功能
    i: 查找包含本文件的文件


7. 查看阅读c++代码[3]
    cscope 缺省只解析C文件(.c和.h)、lex文件(.l)和yacc文件(.y),虽然它也可以支持C++以及Java,但它在扫描目录时会跳过C++及 Java后缀的文件。如果希望cscope解析C++或Java文件,需要把这些文件的名字和路径保存在一个名为cscope.files的文件。当 cscope发现在当前目录中存在cscope.files时,就会为cscope.files中列出的所有文件生成索引数据库。
    下面的命令会查找当前目录及子目录中所有后缀名为".h", ".c", "cc"".cpp"的文件,并把查找结果重定向到文件cscope.files中。然后cscope根据cscope.files中的所有文件,生成符号索引文件。最后一条命令使用ctags命令,生成一个tags文件,在vim中执行":help tags"命令查询它的用法。它可以和cscope一起使用。

    $ find . -name "*.h" -o -name "*.c" -o -name "*.cc" -o "*.cpp" > cscope.files
    $ cscope -bkq -i cscope.files
    $ ctags -R


8. 在vim中使用tags查找符号

    查看ctags帮助
    $ man ctags
:help ctags  (vim command)
    :help tags   (vim command)
    
    在源代码根目录下执行 ctags -R 命令用来为程序源代码生成标签文件,其-R选项表示递归操作,同时为子目录也生成标签文件。vim利用生成的标签文件,可以进行相应检索、并在不同的文件C语言元素之间来回切换。
    $ ctags -R

    A) vim中使用":tag xxx"跳到函数或数据结构xxx处。使用tag命令时,可以使用TAB键进行匹配查找,继续按TAB键向下切换。
    某个函数有多个定义时
    :tag
    跳到第一个定义处,优先跳转到当前文件
    :tnext
    跳到第一个
    :tfirst
    跳到前count个
    :[count]tprevious
    跳到后count个
    :[count]tnext
    跳到最后一个
    :tlast
    你也可以在所有tagname中选择:
    :tselect tagname
    如果想跳到包含block的标识符":tag /block" 然后用TAB键来选择。这里'/'就是告诉vim 'block'是一个语句块标签。

    B) 用"ctrl+]"快捷键,跳转到光标所在函数标识符的定义处。

    C) 使用"ctrl+t"退回上层。 如果想在以write_开头的标识符中选择一下, :tselect /^write_ 这里,'^'表示开头,同理,'$'表示末尾。

    D) 运行vim的时候,必须在"tags"文件所在的目录下运行。否则,运行vim的时候还要用":set tags=xxx"命令设定"tags"文件的路径,这样vim才能找到"tags"文件(这儿我们已经设置过了"set tags=tags;",在子目录中也可以使用)。

    E) 在函数中移动光标的快捷键:
    [{ 转到上一个位于第一列的"{"
    }] 转到下一个位于第一列的"{"
    { 转到上一个空行
    } 转到下一个空行
    gd 转到当前光标所指的局部变量的定义
    * 转到当前光标所指的单词下一次出现的地方
    # 转到当前光标所指的单词上一次出现的地方


9. taglist插件使用[4]
    该 插件可以像Source Insight那样将当前文件中的宏、全局变量、函数等tag显示在Symbol窗口,用鼠标点上述tag,就跳到该tag定义的位置;可以按字母序、该 tag所属的类或scope,以及该tag在文件中出现的位置进行排序;如果切换到另外一个文件,Symbol窗口更新显示这个文件中的tag。 taglist依赖于ctags。

    要使用taglist插件,必须满足:
    1).打开VIM的文件类型自动检测功能;
    2).系统中装了Exuberant ctags工具,并且taglist能够找到此工具(因为taglist需要调用它来生成tag文件);
    3).你的VIM支持system()调用;

    安装taglist插件
    # emerge -av app-vim/taglist

    查看帮助
    :help helptags
    :help taglist
    :help taglist-intro

    打开tag窗口
    :TlistToggle

    .vimrc中配置如下
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" ctags setting
set tags=./tags,./../tags,./*/tags;

" Tag list (ctags)

filetype on                            "文件类型自动检测

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窗口
 
map :TlistToggle     "在映射F8键打开tags窗口
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""


10. 建立索引数据库、查看内核源码[5]
liuby@liuby ~/git/kernel/linux-2.6.30.5 $ make cscope
  GEN     cscope
liuby@liuby ~/git/kernel/linux-2.6.30.5 $ make tags
  GEN     tags
liuby@liuby ~/git/kernel/linux-2.6.30.5 $ ls tags -l
-rw-r--r-- 1 liuby liuby 89648962 03-12 06:12 tags
liuby@liuby ~/git/kernel/linux-2.6.30.5 $ ls cscope.* -l

-rw-r--r-- 1 liuby liuby    403901 03-12 06:02 cscope.files
-rw-r--r-- 1 liuby liuby 182562815 03-12 06:04 cscope.out
-rw-r--r-- 1 liuby liuby  23011328 03-12 06:04 cscope.out.in
-rw-r--r-- 1 liuby liuby 133571208 03-12 06:04 cscope.out.po


11. HOWTO 使用 vim 的 minibuf 来切换缓冲区
1. 安装
到 http://vim.sourceforge.net/scripts/script.php?script_id=159
下载最新版本的 minibufexpl.vim 脚本,
将该文件复制到 ~/.vim/plugin 目录中即可。

2. 配置
在配置文件 ~/.vimrc 中加入:
"
"minibuf plugin
"
let g:miniBufExplMapWindowNavVim = 1 "Ctrl- to move to window
let g:miniBufExplTabWrap = 1 " make tabs show complete (no broken on two lines)

这样就可以使用 minibuf 了,而且设定 Ctrl-h/j/k/l 在各个窗口中切换,很方便。
使用提示:
1. minibuf 占用的就是一个窗口,你可以用 Ctrl-k 切换到其上,然后按 循环选择 buffer
按 则激活该 buffer,按 d 则删除该 buffer
2. 每个 buffer 名称前都有个数字,那是 buffer 的编号,因此,可以输入 :b < buffer编号> 来快速切换。

先自声明,本人是个懒种,因此设定了几个快捷键:
切换至前一缓冲区
切换至后一缓冲区
保存缓冲区(:update 罗)
关闭缓冲区(:bd,或 :bdelete,删除缓冲区)
脚本如下:
nnoremap :call MyCycle buffer(0)
nnoremap 1 :call MyCycle buffer(0)
inoremap :call MyCycle buffer(0)
nnoremap :call MyCycle buffer(1)
nnoremap 2 :call MyCycle buffer(1)
inoremap :call MyCycle buffer(1)
" Cycle Through buffers
" from MiniBufExplorer, modified by DJW
function! MyCycle buffer(forward)
" Change buffer (keeping track of before and after buffers)
let l:origBuf = bufnr('%')
if (a:forward == 1)
bn!
else
bp!
endif
let l:curBuf = bufnr('%')
" Skip any non-modifiable buffers, but don't cycle forever
" This should stop us from stopping in any of the [Explorers]
while getbufvar(l:curBuf, '&modifiable') == 0 && l:origBuf != l:curBuf
if (a:forward == 1)
bn!
else
bp!
endif
let l:curBuf = bufnr('%')
endwhile
endfunction

" delete buffer
nnoremap :bd
nnoremap 4 :bd
inoremap :bd

" or Ctrl-S update buffer
nnoremap :update
inoremap :update
vnoremap :update
nnoremap :update
inoremap :update

这篇关于vim + cscope/ctags/minibuf 查看分析代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/942096

相关文章

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

衡石分析平台使用手册-单机安装及启动

单机安装及启动​ 本文讲述如何在单机环境下进行 HENGSHI SENSE 安装的操作过程。 在安装前请确认网络环境,如果是隔离环境,无法连接互联网时,请先按照 离线环境安装依赖的指导进行依赖包的安装,然后按照本文的指导继续操作。如果网络环境可以连接互联网,请直接按照本文的指导进行安装。 准备工作​ 请参考安装环境文档准备安装环境。 配置用户与安装目录。 在操作前请检查您是否有 sud

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0