首页 > CEDET, IDE, 中级, 自动补全 > 用CEDET浏览和编辑C++代码(续) – 使用Emacs 23.2内置的CEDET

用CEDET浏览和编辑C++代码(续) – 使用Emacs 23.2内置的CEDET

作者: Meteor Liu

1 前言

今天,emacs-23.2发布了,最大的改变就是集成进了CEDET,所以有了这个续, 介绍下build in CEDET和offical CEDET的区别,以及内置CEDET缺少某些功能的替代方案。

PS1:虽然现在官方release版本是1.0pre7,内置的CEDET用cedet-version命令看输入也是1.0pre7,可我总感觉内置的CEDET用起来比官方版本慢很多,我猜想内置的CEDET可能没升级到1.0pre7的release。

PS2:内置CEDET不支持emacs-lisp语言了,没想明白是为什么。

2 semantic配置

2.1 基本配置

官方的CEDET通过semantic-load-enable-minimum-features等几个函数来启动,而内置的CEDET增加了一个单独的minor mode,即semantic-mode,可以通过(semantic-mode)命令来Enable或Disable。

(semantic-mode)是通过semantic-default-submodes这个变量来决定启用哪些minor mode,默认的semantic-default-submodes包含了下面两个minor mode:

  • global-semantic-idle-scheduler-mode
  • global-semanticdb-minor-mode

根据(semantic-mode)的文档,semantic-default-submodes里可以设置下面这些minor mode:

  • global-semanticdb-minor-mode
  • global-semantic-idle-scheduler-mode
  • global-semantic-idle-summary-mode
  • global-semantic-idle-completions-mode
  • global-semantic-decoration-mode
  • global-semantic-highlight-func-mode
  • global-semantic-stickyfunc-mode
  • global-semantic-mru-bookmark-mode

可以根据自己的需要设置,比如我开启了下面4个minor mode:

1
2
3
4
5
(setq semantic-default-submodes '(global-semantic-idle-scheduler-mode
                                  global-semanticdb-minor-mode
                                  global-semantic-idle-summary-mode
                                  global-semantic-mru-bookmark-mode))
(semantic-mode 1)

另外,emacs-23.2的Tools菜单下下新增了”Source Code Parsers (Semantic)”菜单项,可以通过这个菜单项来Enable和Disable semantic-mode,和命令(semantic-mode)的功能是一样的。

此外,官方CEDET里还有其它一些minor mode,现在基本上都还可以用,比如我还打开了下面几个:

1
2
3
(global-semantic-highlight-edits-mode (if window-system 1 -1))
(global-semantic-show-unmatched-syntax-mode 1)
(global-semantic-show-parser-state-mode 1)

关于system-include-dir的设置,还和以前一样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(defconst user-include-dirs
  (list ".." "../include" "../inc" "../common" "../public"
        "../.." "../../include" "../../inc" "../../common" "../../public"))
(defconst win32-include-dirs
  (list "C:/MinGW/include"
        "C:/MinGW/include/c++/3.4.5"
        "C:/MinGW/include/c++/3.4.5/mingw32"
        "C:/MinGW/include/c++/3.4.5/backward"
        "C:/MinGW/lib/gcc/mingw32/3.4.5/include"
        "C:/Program Files/Microsoft Visual Studio/VC98/MFC/Include"))
(let ((include-dirs user-include-dirs))
  (when (eq system-type 'windows-nt)
    (setq include-dirs (append include-dirs win32-include-dirs)))
  (mapc (lambda (dir)
          (semantic-add-system-include dir 'c++-mode)
          (semantic-add-system-include dir 'c-mode))
        include-dirs))

2.2 代码跳转

代码跳转和官方版本一样还是用semantic-ia-fast-jump命令,不过在emacs-23.2里直接用这个命令可能会报下面的错误:

semantic-ia--fast-jump-helper: Symbol's function definition is void: semantic-analyze-tag-references

这可能是emacs的bug,semantic-analyze-tag-references这个函数是定义在semantic/analyze/refs.el这个文件中的,而semantic/ia.el里写的是(eval-when-compile (require ’semantic/analyze/refs)),所以运行时这个feature没被load进来,我们需要自己load一下:

(require 'semantic/analyze/refs)

另外,官方CEDET里semantic-ia-fast-jump后可以通过命令semantic-mrub-switch-tags来回到曾经跳转过的地方,不过在emacs-23.2里会提示:

Semantic Bookmark ring is currently empty

这是因为semantic-ia-fast-jump会用函数push-mark把跳过的地方放到mark ring里去,官方CEDET通过定义push-mark的advice把它也放到了semantic-mru-bookmark-ring里去,semantic-mrub-switch-tags就是从semantic-mru-bookmark-ring来找位置的,但build in的CEDET里把push-mark的advice去掉了,所以semantic-mru-bookmark-ring总是空的,我的办法是把官方CEDET里对push-mark的device拷贝到我的.emacs中来:

1
2
3
4
5
6
7
8
(defadvice push-mark (around semantic-mru-bookmark activate)
  "Push a mark at LOCATION with NOMSG and ACTIVATE passed to `push-mark'.
If `semantic-mru-bookmark-mode' is active, also push a tag onto
the mru bookmark stack."
  (semantic-mrub-push semantic-mru-bookmark-ring
                      (point)
                      'mark)
  ad-do-it)

这样,我以前写的semantic-ia-fast-jump-back函数也能用了:

1
2
3
4
5
6
7
8
9
10
(defun semantic-ia-fast-jump-back ()
  (interactive)
  (if (ring-empty-p (oref semantic-mru-bookmark-ring ring))
      (error "Semantic Bookmark ring is currently empty"))
  (let* ((ring (oref semantic-mru-bookmark-ring ring))
         (alist (semantic-mrub-ring-to-assoc-list ring))
         (first (cdr (car alist))))
    (if (semantic-equivalent-tag-p (oref first tag) (semantic-current-tag))
        (setq first (cdr (car (cdr alist)))))
    (semantic-mrub-switch-tags first)))

对这个函数需要说明一下:网友fangzhzh提过可以用C-u C-space来跳回原来的mark,ahei说可以用C-x C-x来跳回,可我测试这两个按键好像跳得都有点乱,不能和semantic-ia-fast-jump的位置对应。我估计是这两个key是跳回push-mark函数mark的位置,而push-mark不光CEDET用。我的需求是只跳回semantic-ia-fast-jump曾经到过的地方,所以仍然保留了这个函数。

我的习惯还是绑定到F12上:

1
2
3
4
5
6
7
8
(defun semantic-ia-fast-jump-or-back (&optional back)
  (interactive "P")
  (if back
      (semantic-ia-fast-jump-back)
    (semantic-ia-fast-jump (point))))
(define-key semantic-mode-map [f12] 'semantic-ia-fast-jump-or-back)
(define-key semantic-mode-map [C-f12] 'semantic-ia-fast-jump-or-back)
(define-key semantic-mode-map [S-f12] 'semantic-ia-fast-jump-back)

这儿多出来个semantic-ia-fast-jump-or-back函数,是因为我有时候在putty里操作远程的emacs,putty里用不了S-f12这个key,所以我把f12绑定到semantic-ia-fast-jump-or-back上,这样我可以在putty里通过C-u f12来跳回。

以前的semantic-analyze-proto-impl-toggle命令还能用:

(define-key semantic-mode-map [M-S-f12] 'semantic-analyze-proto-impl-toggle)

2.3 代码补全

官方版本里可以用命令semantic-ia-complete-symbol-menu弹出semantic的补全菜单,不过这个命令在内置的CEDET里不存在了(可能是因为emacs官方版本认为这个命令只在GUI下能用,不够通用吧)。

不过,内置的CEDET倒是可以通过命令complete-symbol(默认绑定到ESC-TAB)在另一个buffer里显示可能补全的内容,像这样:

semantic的complete-symbol

如果还希望能使用补全菜单,可以使用其它插件,比如auto-complete或company-mode:company-mode-0.5已经可以支持emacs内置的CEDET了;auto-complete-1.2对内置CEDET的支持还有些问题,关于如何配置auto-complete-1.2让它支持内置的CEDET,我准备另外写文章介绍。

3 EDE配置

ede和官方版本没有区别,仍然用(global-ede-mode t)启用就行了;不过emacs-23.3的Tools菜单下新增了”Project support (EDE)”菜单项,可以完成global-ede-mode一样的功能。

4 其它

4.1 可视化书签

官方CEDET里的visual-studio-bookmarks在内置的CEDET里没有了,所以我现在使用bm了。

4.2 pulse

pulse的功能在内置CEDET里还存在,不过官方CEDET里可以用pulse-toggle-integration-advice函数来切换pulse,在内置CEDET里这个函数消失了,现在的办法是设置pulse-command-advice-flag变量来切换:

(setq pulse-command-advice-flag (if window-system 1 nil))

另外,官方版本里对下面这些函数设置了pulse的device:

  • goto-line
  • exchange-point-and-mark
  • find-tag
  • tags-search
  • tags-loop-continue
  • pop-tag-mark
  • imenu-default-goto-function

内置版本里这些device都没了,所以我直接把官方版本里的advice拷贝过来了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
(defadvice goto-line (after pulse-advice activate)
  "Cause the line that is `goto'd to pulse when the cursor gets there."
  (when (and pulse-command-advice-flag (interactive-p))
    (pulse-momentary-highlight-one-line (point))))
(defadvice exchange-point-and-mark (after pulse-advice activate)
  "Cause the line that is `goto'd to pulse when the cursor gets there."
  (when (and pulse-command-advice-flag (interactive-p)
             (> (abs (- (point) (mark))) 400))
    (pulse-momentary-highlight-one-line (point))))
(defadvice find-tag (after pulse-advice activate)
  "After going to a tag, pulse the line the cursor lands on."
  (when (and pulse-command-advice-flag (interactive-p))
    (pulse-momentary-highlight-one-line (point))))
(defadvice tags-search (after pulse-advice activate)
  "After going to a hit, pulse the line the cursor lands on."
  (when (and pulse-command-advice-flag (interactive-p))
    (pulse-momentary-highlight-one-line (point))))
(defadvice tags-loop-continue (after pulse-advice activate)
  "After going to a hit, pulse the line the cursor lands on."
  (when (and pulse-command-advice-flag (interactive-p))
    (pulse-momentary-highlight-one-line (point))))
(defadvice pop-tag-mark (after pulse-advice activate)
  "After going to a hit, pulse the line the cursor lands on."
  (when (and pulse-command-advice-flag (interactive-p))
    (pulse-momentary-highlight-one-line (point))))
(defadvice imenu-default-goto-function (after pulse-advice activate)
  "After going to a tag, pulse the line the cursor lands on."
  (when pulse-command-advice-flag
    (pulse-momentary-highlight-one-line (point))))

另外,我还喜欢对下面这些函数定义pulse:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
(defadvice cua-exchange-point-and-mark (after pulse-advice activate)
  "Cause the line that is `goto'd to pulse when the cursor gets there."
  (when (and pulse-command-advice-flag (interactive-p)
             (> (abs (- (point) (mark))) 400))
    (pulse-momentary-highlight-one-line (point))))
(defadvice switch-to-buffer (after pulse-advice activate)
  "After switch-to-buffer, pulse the line the cursor lands on."
  (when (and pulse-command-advice-flag (interactive-p))
    (pulse-momentary-highlight-one-line (point))))
(defadvice previous-buffer (after pulse-advice activate)
  "After previous-buffer, pulse the line the cursor lands on."
  (when (and pulse-command-advice-flag (interactive-p))
    (pulse-momentary-highlight-one-line (point))))
(defadvice next-buffer (after pulse-advice activate)
  "After next-buffer, pulse the line the cursor lands on."
  (when (and pulse-command-advice-flag (interactive-p))
    (pulse-momentary-highlight-one-line (point))))
(defadvice ido-switch-buffer (after pulse-advice activate)
  "After ido-switch-buffer, pulse the line the cursor lands on."
  (when (and pulse-command-advice-flag (interactive-p))
    (pulse-momentary-highlight-one-line (point))))
(defadvice beginning-of-buffer (after pulse-advice activate)
  "After beginning-of-buffer, pulse the line the cursor lands on."
  (when (and pulse-command-advice-flag (interactive-p))
    (pulse-momentary-highlight-one-line (point))))

4.3 h/cpp切换

官方CEDET里的eassist.el没有了,所以eassist-switch-h-cpp也没了,现在我用sourcepair代替,sourcepair比eassist-switch-h-cpp更好用。

4.4 代码折叠

semantic-tag-folding.el没有了,可我没找到其它更好的替代方案,所以我把官方CEDET里的semantic-tag-folding.el拷过来了,只需要把文件中(require ’semantic-decorate-mode)替换成(require ’semantic/decorate/mode)就能像以前一样用了。

以前的senator-fold-tag功能还可以使用。

最后插播个广告,我关于内置CEDET的配置(最后那部分):http://github.com/meteor1113/dotemacs/blob/master/init-basic.el

分享家:Addthis中国
GD Star Rating
loading...
用CEDET浏览和编辑C++代码(续) - 使用Emacs 23.2内置的CEDET, 8.7 out of 10 based on 27 ratings 标签:ahei, C/C++, CEDET, company-mode, cursor, ede, Emacs, emacser, emacser.com, highlight, imenu, lambda, meteor, meteor1113, org, pulse, putty, screenshot, semantic, senator, windows, 代码折叠, 代码补全, 插件, 补全, 配色, 配色

相关日志

  1. 2017年9月18日16:36 | #1

    Superb, what a website it is! This blog presents useful data to us,
    keep it up.

    [回复]

评论分页
1 ... 3 4 5 41327
  1. 2010年5月10日02:29 | #1
  2. 2011年10月4日03:43 | #2
  3. 2012年5月27日19:03 | #3
  4. 2012年6月10日10:33 | #4
  5. 2014年6月3日05:43 | #5
  6. 2014年6月25日01:58 | #6
  7. 2014年6月27日08:59 | #7
  8. 2017年6月13日22:01 | #8
  9. 2017年6月18日01:02 | #9
  10. 2017年6月30日22:41 | #10
  11. 2017年10月28日20:51 | #11
:wink: :-| :-x :twisted: :) 8-O :( :roll: :-P :oops: :-o :mrgreen: :lol: :idea: :-D :evil: :cry: 8) :arrow: :-? :?: :!: