cedet 的定制,(译文)
Table of Contents
- 1. Customization
- 2. Semantic's customization
- 3. Optimization of Semantic's work
- 4. Customization of Semanticdb
- 5. How to customize Semantic to work with C & C++ projects
- 6. Preprocessing of source code
- 7. Work with Semantic
- 8. Names completion
- 9. Getting information about tags
- 10. Search for places where function is called
- 11. Source code folding
- 12. Work with Srecode
- 13. Additional packages
1 Customization
Cedet最简单的配置就是加载cedet.el
(load-file "~/emacs/cedet/common/cedet.el")
关于emacs23.2中加载cedet.el的一些配置见另一篇文章,这里不多说了 如果还想用Cedet 对项目进行管理可以再加上一这句
(global-ede-mode t)
2 Semantic's customization
这个需要根据你的需求来进行配置 你可以用下面的命令来实现相应的功能.它们的功能是依次增强的, 下面的命令会包含它上面的命令所有的功能.
- semantic-load-enable-minimum-features — 只启用最少的功能,仅仅对
当前的buffer进行语法的采集,并将收集到的信息存到(Semanticdb)中,以后 可以使用Semanticdb 和Ebrowse 得用采集到的信息进行相应的处理.
- semantic-load-enable-code-helpers —
启用 senator-minor-mode mode,可以实现在buffer间进行代码的导航(跳转). 启用semantic-mru-bookmark-mode,存储你访问过的tags的位置及 semantic-idle-summary-mode显示光标下所处的tag的相应信息.
- semantic-load-enable-gaudy-code-helpers — 启用 semantic-stickyfunc-name 将当前buffer中的所有函数列在 buffer最前面的几行处, 启用semantic-decoration-mode 用不同的faces来装饰tags 启用semantic-idle-completion-mode会在用户停止输入内容的时候自动产生可用的名称补全.
- semantic-load-enable-excessive-code-helpers — 启用which-func-mode ,在状态栏显示当前的函数名称.
- semantic-load-enable-semantic-debugging-helpers —
启用了多种modes 在用Semantic时进行debug操作时可以展现出现的解析错 误及状态等.
对以上命令你只需根据你的需要,在load cedet.el后运行其中的一个命令 如
(semantic-load-enable-excessive-code-helpers)
下面的部分会解释一下Semantic的一些简单特性. 如果想要得用名称的补全及显示tags ,classes相应的信息,你可以需要 加载 semantic-ia
(require 'semantic-ia)
运行了这个语句后,下面的命令就可以使用了. 为了正常使用系统及的函数库Semantic应该具有接触觉系统include 文件的权限. 其中含有一此关于函数 数据类型的相信息. 如果你使用gcc 编译C/C++文件,Semantic可以自动寻找相应的 include路径 为了达到这个目换,需要下面这个命令来实现
(require 'semantic-gcc)
当然你也可以显式的指定include的路径, semantic-add-system-include函数可以实现这个功能 它需要两个参数
- include files 的路径,及相应的major-mode,例如:
(semantic-add-system-include "~/exp/include/boost_1_37" 'c++-mode)
3 Optimization of Semantic's work
为了优化tags ,有以下几个技巧 *通过声明一个EDE project来限制搜索的范围: *显式的声明有关你的项目root 目录,Semantic就会用有限的几个databases 来存储语法信息.
- 可以为常用的目录事先生成tags databases semanticdb-create-ebrowse-database semanticdb-create-cscope-database 命令可以实现此功能.
- 用semanticdb-find-default-throttle变量为具体的mode来限制搜索的范
围,例如:不使用系统级的include files ,为c-mode通过从对像列表中移除系统级的变量 (setq-mode-local c-mode semanticdb-find-default-throttle '(project unloaded system recursive)) Semantic收集语法信息的机制在利用Emacs空闲的时间来完成的.,你可以设置 semantic-idle-scheduler-idle-time 的值来控制空闲多长时间才开始进行收集工作,单位是秒.
Integration with imenu Semantic可以与imenu进行整合.可以以菜单的形式列出可用的 functions,variables,及其他的tags semantic-load-enable-code-helpers级即可以实现此功能 或者通过下面的代码也可以实现
(defun my-semantic-hook () (imenu-add-to-menubar "TAGS")) (add-hook 'semantic-init-hooks 'my-semantic-hook)
4 Customization of Semanticdb
如果你使用默认的加载cedet.el的方式 ,那么Semanticdb已经自动加载了 如果没有的话可以用下面的方式实现
(require 'semanticdb) (global-semanticdb-minor-mode 1)
对Semanticdb进行定制,你可以设定semanticdb的存储位置 具体见customize-group semanticdb.
另外semanticdb可以得用其他的外部工具生成的databased 诸如gtags(GNU/Global) ,ctags ,ebrower, cscope 下面的命令支持gnu/global
(require 'semanticdb-global) (semanticdb-enable-gnu-global-databases 'c-mode) (semanticdb-enable-gnu-global-databases 'c++-mode)
为 Unix Shell, Perl, Pascal, Tcl, Fortran, Asm等语言起用 ctags支持
(semantic-load-enable-primary-exuberent-ctags-support)
5 How to customize Semantic to work with C & C++ projects
为了让Semantic更好的为C/C++工作,推荐使用EDE 对其进行项目的管理. EDE定义特定的project 类型ede-cpp-root-project,它提供额外的Semantic信息. 可以用于分析人项目中的代码. 为了定义一个项目,需要用下面方法来定义一个项目. (ede-cpp-root-project "Test" :name "Test Project" :file "~/work/project/CMakeLists.txt" :include-path '("/" "/Common" "/Interfaces" "/Libs" ) :system-include-path '("~/exp/include") :spp-table '(("isUnix" . "") ("BOOSTTESTDYNLINK" . ""))) 你可以使用项目根目录下的任何一个文件在作为:file的值, 它的意义仅是让Semantic找到项目的根目录而已 Semantic 从:system-include-path ,:include-path两个参数指定的位置 搜索include files.在:include-path中如果路径以"/"开头,表示它是相对于项 目根目录的.你不仅可以用目录名作参数,还可以是一个搜索include files 的 函数,具体见EDE的手册 :spp-table 是一系列的键值对,上面的例子定义了两个symbols isUnix BOOSTTESTDYNLINK,它们会被传递给preprocessor,对于代码的解析有一定的 帮助 用户如果有必要可以重定义一些与项目内文件有关的变量.通过 :local-variables变量可以实现,其值与:spp-table一样是键值对
6 Preprocessing of source code
更详细的关于 preprocessor的内容见 semantic-lex-c-preprocessor-symbol-map 变量 可以通过semantic-lex-spp-describe命令获得与preprocessor symbols定义相 关的的一些内容 .然后用它来配置你的:spp-table或者 semantic-lex-c-preprocessor-symbol-map变量.
很多库都是把预先定义的macros包含在一个include file .所以你可以利用它. 为此,你需要用在semantic-lex-c-preprocessor-symbol-file变量为列出 这样的文件,当Cedet进行语法分析的时候就会得用其中的内容. 默认情况下它只有一个值C++的标准库:作为一个例子,我来告诉你 如何配置QT4
(setq qt4-base-dir "/usr/include/qt4") (semantic-add-system-include qt4-base-dir 'c++-mode) (add-to-list 'auto-mode-alist (cons qt4-base-dir 'c++-mode)) (add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qconfig.h")) (add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qconfig-dist.h")) (add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qglobal.h"))
此后你就可以得用QT4库中定义的类了,下面是截图.
7 Work with Semantic
Semantic提供了几种补全方式,收集tags信息(变量,函数等),及在代码间导航. 其中一些内容是semantic-ia包实现的,还有一些是Senator实现的,剩下的就是 Semantic内核实现的了.
一些命令没有进行键绑定,你需要自已进行绑定
(defun my-cedet-hook () (local-set-key [(control return)] 'semantic-ia-complete-symbol) (local-set-key "\C-c?" 'semantic-ia-complete-symbol-menu) (local-set-key "\C-c>" 'semantic-complete-analyze-inline) (local-set-key "\C-cp" 'semantic-analyze-proto-impl-toggle)) (add-hook 'c-mode-common-hook 'my-cedet-hook)
另外需要提及的一点的Semantic的开发工作是相当活跃的,如果semantic不能很 好得处理你的代码,你可以给cedet-devel 邮件列表发送你的代码帮助他们改进
8 Names completion
对函数 变量 类名进行名称的补全 Semantic内部有两个package实现了这个功能 semantic-ia和Senator.semantic-ia 用 semantic-analyze-possible-completions 来创建可用的 补全列表, 它有多个参数,用户甚至可以扩展它进行更精确的补全. Senator则用简单的方法来创建补全列表,它只得用当前buffer的内容来提供补全 内容,所以用时它的补全并不准确.
当你在键入代码时运行 semantic-ia-complete-symbol命令,就会激活名称的补 全(包括变量 类名 方法名)如果有多个内容,这几个候选项最基本的内容会首先 被补全上,二次调用此命令所有的可选列表会被列出来.你可以用 semantic-ia-complete-symbol-menu 命令来选择(通过菜单方式) semantic-ia-complete-tip命令会通过tooltip的方式列出可用的补全.
Senator的补全会快速一些(但也相对性简单),senator-complete-symbol(`C-c,TAB') 会补全当前tag,并插入第一个找到的候选项.重复命令会依次选中第二个…,如 果你想看所有的可用补全senator-completion-menu-popup(C-c,SPC) 可以实现
除了上面的命令对于一些语言可以使用某些特定的mode semantic-idle-completions-mode, 这个mode会在emantic-load-enable-gaudy-code-helpers级别启用. 在这个级别上补别的名称会自动显现,如果用户有一段时间没有键入,那么 它就会停止补全,默认情况下,只有第一个选项显示出来,用户可以用TAB 在可选项中导航 对于类C的语言,用户可以用semantic-complete-self-insert 命令 可以绑定在 "." 和 ">"键上. (defun my-c-mode-cedet-hook () (local-set-key "." 'semantic-complete-self-insert) (local-set-key ">" 'semantic-complete-self-insert)) (add-hook 'c-mode-common-hook 'my-c-mode-cedet-hook) 当用记键入"." 及">"时,就会列出可选的补全内容.
9 Getting information about tags
semantic-ia包提供了几个收集变量函数类名信息的命令. semantic-ia-show-doc 显示光标下的函数和变量的文档信息,文档信息在另一个buffer 中显示. 对于变量,这会显示变量的类型,及文档描述.对于函数,函数的定义部分 会显示出来.包括返回值及参数信息.
semantic-ia-show-summary 显示光标下的name的文档信息.不过内容是在minibuffer中显示,用户仅能看 到变量的定义及函数的声明. semantic-ia-describe-class 用户输入一个类名,列出此类及其父类中的所有函数及变量, Navigation in source code semantic-ia-fast-jump 是代码跳转的一个命令,可以跳到变量或者函数的 声明部分.semantic-mrub-switch-tag(C-x B) 可以跳回来 必须启用semantic-mru-bookmark-mode mode. Semantic 还提供了在当前buffer或者当前project中进行跳转的命令 semantic-complete-jump-local (C-c j) semantic-complete-jump(C-c ,J) 两个命令都可以让用户输入要跳转的类名变量名等 semantic-ia-fast-jump semantic-complete-jump 的主要差别是前者可以分析的内容如this::that->foo() 后者仅能分析简单的name,像foo.
semantic-analyze-proto-impl-toggle 命令可以在函数的声明和实现部分进行 跳转(对于那些声明和实现可以在不同部分存放的函数) semantic-decoration-include-visit 可以在光标下name 的include 文件间跳 转. senator-next-tag (C-c , n) senator-previous-tag (C-c , p) 在前后tag间移动 senator-go-to-up-reference command (C-c , u), that move cursor to the "parent" tag 例如 函数的上层tag就是类的声明
10 Search for places where function is called
semantic-symref命令 可以查找到光标下变量的在本项目中声明位置 semantic-symref-symbol 可以输入你想要找的具体变量名.
如果某些名称没有在相应的database(如gnu/global,)中找到,它会用 find-grep命令尝试搜索.可以在打开的新buffer中找到你要找的变量进行跳转.
11 Source code folding
Semantic可以实现代码折叠.跟hideshow.el提供的功能类似 global-semantic-tag-folding-mode 实现这个功能. 不仅可以折叠代码,还可以折叠注释.
Senator有相似的函数 ,不会它通常用于top-level级的对象,如 function ,class 声明等. senator-fold-tag (C-c , -)可以折叠小段代码 senator-unfold-tag (C-c , +).
Senator还提供了便于copy cut tag的命令, cut当前tag用 senator-kill-tag(C-c , C-w) 用C-y可以在别处粘贴. senator-yank-tag command (C-c , C-y) 仅粘贴声明部分 senator-copy-tag (C-c , M-w),copy当前函数到include文件 这个命令就很有用了
Senator可以改变默认的搜索命令如 (re-search-forward, isearch-forward and other) senator-isearch-toggle-semantic-mode (C-c , i) 激活此功能,然后用 senator-search-set-tag-class-filter command (C-c , f) 仅search class variable functions.
senator-search-forward senator-search-backward 即使没激活.senator-isearch-toggle-semantic-mode,也可以用这两个命令.
12 Work with Srecode
可用于定义及插入代码模版.它是contextable的, 比如插入set/get 的模版仅在类的声明内部才有用 ,函数的插入不会在函数内部激活. srecode-insert /C-c / / 然后输入要插入的名 srecode-insert-again command (C-c / .). 插入同一个模版.
不同的模版也可以有各自的键绑定 C-c / [a..z], 如在C++mode C-c / c 插入类的声明 对于大写字母的键绑定,保留给模版使用的 如c-c / G (srecode-insert-getset) 插入get/set C-c / E (srecode-edit) 编辑模版 用户定义的模版可放在~/.srecode下,关于如何创建,见手册
13 Additional packages
eassist-list-methods 列出当前buffer中定义的函数,并可以进行跳转 eassist-switch-h-cpp 可以在include file 和源码间跳转.