ascope.el --在 Emacs 中使用 cscope

 

原来一直使用 etags,它简单而且速度很快,我很喜欢。但有一点却非常不方便,就是在搜索结果中找想要的东西。如果定位到的不是你想要的,就要一次次按 C-u M-.,希望着你运气足够好下一个就碰到,有时实在把耐心都按到没有了。为此我终于开始使用 cscope,它的口碑也不错哈。cscope 在 Emacs 中的接口有好几个,我没有兴趣都试一遍。但是曾经用过 xcscope.el,它的速度为人所诟病。我感觉了一下,确实与 ascope.el 有些差别,但是现在硬件强大了,这个问题显得不是那么严重了。其实 ascope.el 最吸引的我是它的小巧,让我有勇气把它读一读,而且作者在 xcscope.el 和 bscope.el 之间取折中的想法我比较认同。

下面就我修改过的  ascope.el 版本,简要介绍一下如何使用。

先在 .emacs 中,添加:
(require 'ascope)


就可以使用,下面这些函数了:

;; M-x ascope-init
ascocpe-init 加载 tag table 并进行初始化工作,一般不需要手动运行,第一次查询之前会提示加载。

;; M-x ascope-find-global-definition
;; M-x ascope-find-this-symbol
;; M-x ascope-find-this-text-string
;; M-x ascope-find-this-egrep-pattern
;; M-x ascope-find-functions-calling-this-function
;; M-x ascope-find-called-functions
;; M-x ascope-find-this-file
;; M-x ascope-find-files-including-file
分别对应 cscope 相应功能,是查询使用的命令。

;; M-x ascope-pop-marker
回到这次查询开始时的位置,相当于 etags 里面的 pop-tag-mark。

;; M-x ascope-clear-overlay-arrow
除去那个 "=>" (遇到你就知道是什么了呵),一般不用手动运行,因为 ascope-select-entry-other-window-delete-window 会自动消除它。

;; M-x ascope-search-symbol-in-cache
在查询过的 cache 中快速定位,下面我会再提到。

因为,通常的查询还是查询定义,所以我按 etags 的习惯,在 .emacs 中作了如下绑定:

(global-set-key [?\M-*] 'ascope-pop-marker)
(global-set-key [?\M-,] 'ascope-search-symbol-in-cache)
(global-set-key [?\M-.] 'ascope-find-global-definition)

查询结果显示在 buffer *Result* 里面,可以使用下面的命令和对应的按键移动光标或选定要找的内容。

;; these commands are bound in the search result buffer (*Result*)
;; ascope-show-this-entry-other-window is bound to key "Space"
;; ascope-show-next-entry-other-window is bound to key "n"
;; ascope-show-prev-entry-other-window is bound to key "p"
;; ascope-select-entry-other-window-delete-window is bound to key "enter"
;; ascope-buffer-quit is bound to key "q" and "0"
;; ascope-buffer-next-entry is bound to key "TAB"
;; ascope-buffer-prev-entry is bound to key "M-TAB"


命令的名字已经足够说明用途了,对应的绑定键也很明了。只说说,*-show-* 、 *-select-* 命令与 ascope-buffer-*-entry 的区别,就是后者不会打开文件,只是移动光标。因为一般情况下,一看就知道要找是哪个 entry ,比如查某结构体定义,像这行直接就可以看出来:

*** /home/lei/kernel/include/linux/mm_types.h:
mm_struct[315]                 struct mm_struct {


不用 n 或 p 到它时打开所有经过的 entry。而前二者之间的区别是,*-select-* 会删除其它窗口。


如何使用就算讲完了,再啰嗦一下背后的故事。ascope.el 快,快在哪里?就在它使用 "-ld" 参数运行 cscope,这样不用每次查询都启动程序并加载 tag table。但是,有时我们可以更快一些,比如,如果我发现自己忘了查过的一个符号定义,再来一次输入、查询、选择的过程?重复劳动是可以避免的,所以我 给 ascope.el 加入了 cache 功能。它记录查询过的符号对应的 buffer 、file 和 point,buffer 存在时直接切换到它并定位到 point 。如果不存在,例如已经 kill 掉了,就先打开 file。Emacs 退出时会把 cache 保存在一个文件里(文件名默认为 ascope.cache ,与 cscope.out 存放在同一个目录)。这样随着你查询的东西越来越多,它会保存的越来越多,以后你会越来越省时间。

值得一提的有两点,一是查询的符号重名时,新的会替换掉旧的,这样最终保存下的就是最后查询的,也最可能是我们下次想要找的;二是如果 cscope.out 变了呢?很多之前的定位都可能不准了。每次加载 cache 时,它使用 sha1sum 计算当前 cscope.out 的散列值,如果没有改变就加载,如果改变了会提醒是否加载,让用户选择。选"否"的话 cache 内容全部丢弃;选"是"的话,仍然加载旧的 cache ,那就在以后发现某个符号定位不准时,用 *-find-* 进行新的查询来进行更新。

要说的就这些。总之,如果你在 Emacs 中使用 cscope 的话,ascope.el 可以试一试。

 

转载于:https://www.cnblogs.com/wang-lei/archive/2012/08/16/2641048.html

你可能感兴趣的:(ascope.el --在 Emacs 中使用 cscope)