imenu可以定位C/C++文件里的函数,配合anything使用,非常方便。可是我却发现,它无法定位带有函数指针作为参数的函数,如gcc/genattrtab.c里面的
static rtx
substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
rtx (*address_fn) (rtx))
查看imenu的代码后发现,原来imenu是一个framework,具体的定位功能,是由相应的major mode实现的,我发现的问题,其实是cc-mode的实现有缺陷。在报了bug几天后,CC mode maintainer解决了这个问题。如果暂时没法(或不愿意)升级到最新的开发版,可以在自己的.emacs文件里添加如下配置,对于已经打开的文件,需要revert-buffer才能奏效。两个setq语句是从lisp/progmodes/cc-menus.el里摘录出来,如果下面的代码看不清楚,可以从源文件里直接复制。
(eval-after-load 'cc-mode
'(progn
(setq cc-imenu-c++-generic-expression
`(
;; Try to match ::operator definitions first. Otherwise `X::operator new ()'
;; will be incorrectly recognised as function `new ()' because the regexps
;; work by backtracking from the end of the definition.
(nil
,(concat
"^\\< .*"
"[^" c-alnum "_:<>~]" ; match any non-identifier char
; (note: this can be `\n')
"\\("
"\\([" c-alnum "_:<>~]*::\\)?" ; match an operator
"operator\\>[ \t]*"
"\\(()\\|[^(]*\\)" ; special case for `()' operator
"\\)"
"[ \t]*([^)]*)[ \t]*[^ \t;]" ; followed by ws, arg list,
; require something other than
; a `;' after the (...) to
; avoid prototypes. Can't
; catch cases with () inside
; the parentheses surrounding
; the parameters. e.g.:
; `int foo(int a=bar()) {...}'
) 1)
;; Special case to match a line like `main() {}'
;; e.g. no return type, not even on the previous line.
(nil
,(concat
"^"
"\\([" c-alpha "_][" c-alnum "_:<>~]*\\)" ; match function name
"[ \t]*(" ; see above, BUT
"[ \t]*\\([^ \t(*][^)]*\\)?)" ; the arg list must not start
"[ \t]*[^ \t;(]" ; with an asterisk or parentheses
) 1)
;; General function name regexp
(nil
,(concat
"^\\< " ; line MUST start with word char
;; \n added to prevent overflow in regexp matcher.
;; http://lists.gnu.org/archive/html/emacs-pretest-bug/2007-02/msg00021.html
"[^()\n]*" ; no parentheses before
"[^" c-alnum "_:<>~]" ; match any non-identifier char
"\\([" c-alpha "_][" c-alnum "_:<>~]*\\)" ; match function name
"\\([ \t\n]\\|\\\\\n\\)*(" ; see above, BUT the arg list
"\\([ \t\n]\\|\\\\\n\\)*" ; must not start
"\\([^ \t\n(*]" ; with an asterisk or parentheses
"[^()]*\\(([^()]*)[^()]*\\)*" ; Maybe function pointer arguments
"\\)?)"
"\\([ \t\n]\\|\\\\\n\\)*[^ \t\n;(]"
) 1)
;; Special case for definitions using phony prototype macros like:
;; `int main _PROTO( (int argc,char *argv[]) )'.
;; This case is only included if cc-imenu-c-prototype-macro-regexp is set.
;; Only supported in c-code, so no `:<>~' chars in function name!
,@(if cc-imenu-c-prototype-macro-regexp
`((nil
,(concat
"^\\< .*" ; line MUST start with word char
"[^" c-alnum "_]" ; match any non-identifier char
"\\([" c-alpha "_][" c-alnum "_]*\\)" ; match function name
"[ \t]*" ; whitespace before macro name
cc-imenu-c-prototype-macro-regexp
"[ \t]*(" ; ws followed by first paren.
"[ \t]*([^)]*)[ \t]*)[ \t]*[^ \t;]" ; see above
) 1)))
;; Class definitions
("Class"
,(concat
"^" ; beginning of line is required
"\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a `template < ...>'
"\\(class\\|struct\\)[ \t]+"
"\\(" ; the string we want to get
"[" c-alnum "_]+" ; class name
"\\(< [^>]+>\\)?" ; possibly explicitly specialized
"\\)"
"\\([ \t\n]\\|\\\\\n\\)*[:{]"
) 3)))
(setq cc-imenu-c-generic-expression
cc-imenu-c++-generic-expression)))






看了下wiki,感觉功能上和ecb有点类似,不知您平常是怎么用的,体验如何
配合anything使用,anything-config.el里面有anything-c-source-imenu,直接拿来用。
话说如果开启了 ido-ubiquitous 的话,anything 就没什么作用了吧,感觉两者功能差不多?
没有接触过ido,有机会学习一下。