在emacs中使用像source insight 一样的函数预览窗口(升级版)

Vim、Emacs配置和使用
yupeng820921
帖子: 94
注册时间: 2009-02-25 19:44

在emacs中使用像source insight 一样的函数预览窗口(升级版)

#1

帖子 yupeng820921 » 2009-04-22 23:33

以前就写过一个类似的小程序,这次又改进了一下。

这个程序主要用于在emacs中读程序时使用鼠标导航,预设功能是这样的:

先建立一个名叫“*preview*"的buffer。

鼠标左键单击一个函数或变量名,在“*preview*" buffer中显示出函数或变量的定义。
鼠标中键点击一个函数或变量名,在“*preview*" buffer中显示出函数或变量被调用的地方。

如果某个函数的定义只有唯一一处,那么“*preview*" buffer就会显示出它的定义所在。鼠标左键单击“*preview*" buffer可以把该定义所在的文件打开到另一个buffer。如果函数的定义不唯一,那么“*preview*" buffer会列出所有定义该函数的地址,鼠标左键单击任一地址可以在“*preview*" buffer中显示该定义,左键单击可以在另一个窗口中打开该文件,或者右键单击“*preview*" buffer可以返回到地址列表。

当跳转到一个函数的定义后,单击鼠标右键可以返回到跳转前的地方。对于变量定义以及函数和变量的调用也类似。

大体上,行为就和source insight 或slick editor这些代码浏览工具差不多。

需要重点说明的是,我这个程序只是一个前端显示程序,它依赖于cedet 和gnu global,必须要把这两者装好,否则我这个程序无法工作。

下载附件中的程序,安装方法是emacs扩展的标准方法,在.emacs中加上这几句话:

(require 'yp-preview)
(pv-enable)

(defun my-pv-c-map ()
(interactive)
(define-key c-mode-map [mouse-1] 'pv-find-def-and-delay)
(define-key c-mode-map [mouse-2] 'pv-find-ref-or-paste)
(define-key c-mode-map [mouse-3] 'pv-pop-mark)
)

(add-hook 'c-mode-hook 'my-pv-c-map)

这样,就可以在emacs中用鼠标进行导航了。

呃,还有个不得不说的问题,这个扩展要用的舒服,还需要ecb,把"*preview*" buffer加入到ecb的compile buffer列表里面,我只会直接改动ecb的源程序然后直接编译,这是我自己在ecb-compilation.el中对ecb-compilation-buffer-name做的修改:

(defcustom ecb-compilation-buffer-names `(("*Calculator*" . nil)
("*vc*" . nil)
("*vc-diff*" . nil)
("*preview*" . nil)
,(if ecb-running-xemacs
'("\\*Apropos.*\\*" . t)
'("*Apropos*" . nil))
("*Occur*" . nil)
("*shell*" . nil)
("\\*[cC]ompilation.*\\*" . t)
("\\*i?grep.*\\*" . t)
("*JDEE Compile Server*" . nil)
,(if ecb-running-xemacs
'("\\*Help.*\\*" . t)
'("*Help*" . nil))
("*Completions*" . nil)
("*Backtrace*" . nil)
("*Compile-log*" . nil)
("*bsh*" . nil)
(,(if ecb-running-xemacs
" *Message-Log*"
"*Messages*") . nil))
"*Additional buffer names that should be displayed in the compile-window.
Buffer names can either be defined as strings or as regexps. If the
buffer-name of a buffer matches one of the defined string or regexp then it
will be displayed in the compile-window of ECB even if `compilation-buffer-p'
says nil for this buffer.

It is not recommended to add the name of eshell-buffers to this list because
ECB already handles the eshell-integration as best as possible.

See also the options `ecb-compilation-major-modes' and
`ecb-compilation-predicates'."
:group 'ecb-compilation
:group 'ecb-most-important
:type '(repeat (cons (string :tag "Buffer name")
(boolean :tag "Handled as regexp"))))

这样,使能ecb 的compilation buffer之后就几乎可以和source insight 以及slick editor 的样子差不多了。

现在已知两个问题,一是如果在cedet中使能对global 的支持的话每次调用semantic分析都会调用一次global,把global找到的东西打开把line-number转换成point-number,再把这些文件关闭。这样其实效率很低,如果没必要的话干脆就不要打开semantic对global的支持好了,我这个扩展自己也会调用global. 如果你用ede建立了一个project的话可以在ede中使能global,这没关系。另一个问题就是我这个扩展在linux下很正常,在windows下会有及个别的文件用鼠标点击后会乱蹦,不知道咋回事,没理它。

基本上,我就是按照我自己的喜好弄的,可能不符合别人的胃口,谁有什么好的建议可以把它做得通用一点,可以跟我提提。
附件
yp-preview.el.tar.gz
(3.22 KiB) 已下载 94 次
上次由 yupeng820921 在 2010-05-30 10:56,总共编辑 1 次。
头像
yjcong
帖子: 2470
注册时间: 2006-02-28 3:11

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#4

帖子 yjcong » 2009-04-22 23:55

xemacs能用吗?
一梦三年,
松风依旧,
萝月何曾老.


灵幽听微, 谁观玉颜?
灼灼春华, 绿叶含丹.
yupeng820921
帖子: 94
注册时间: 2009-02-25 19:44

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#5

帖子 yupeng820921 » 2009-04-23 13:03

yjcong 写了:xemacs能用吗?
我没试过,不过我估计如果在xemacs上能正常运行cedet和global的话我这个程序就应该能正常运行。
头像
yjcong
帖子: 2470
注册时间: 2006-02-28 3:11

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#6

帖子 yjcong » 2009-04-23 23:43

我这现在global装不了, 说 Unknown host, NND
一梦三年,
松风依旧,
萝月何曾老.


灵幽听微, 谁观玉颜?
灼灼春华, 绿叶含丹.
yupeng820921
帖子: 94
注册时间: 2009-02-25 19:44

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#7

帖子 yupeng820921 » 2009-04-24 22:05

yjcong 写了:我这现在global装不了, 说 Unknown host, NND

呃,你是装gnu global吗?编译没通过还是没办法在(x)emacs中运行?在命令行下能运行不?
头像
yjcong
帖子: 2470
注册时间: 2006-02-28 3:11

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#8

帖子 yjcong » 2009-04-24 22:40

用apt安装的。那个host的问题要改/etc下的文件, 但我没找到该改的地方
一梦三年,
松风依旧,
萝月何曾老.


灵幽听微, 谁观玉颜?
灼灼春华, 绿叶含丹.
yupeng820921
帖子: 94
注册时间: 2009-02-25 19:44

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#9

帖子 yupeng820921 » 2009-04-25 19:43

我都是直接在gnu的网站上下载的,然后源码安装。建议你也源码安装吧。

看gnu global的小版本升级了我还进行了几次更新,./configure, make, make install, 一直都没出过问题,也从来没改过什么/ect下的文件。
头像
yjcong
帖子: 2470
注册时间: 2006-02-28 3:11

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#10

帖子 yjcong » 2009-04-27 0:17

鼠标左键单击“*preview*" buffer可以把该定义所在的文件打开到另一个buffer。
实现不了。

在/usr/share/emacs/site-lisp/ecb/ecb-compilation.el中和ecb-compilation-buffer-name有关的只有
(if (and ecb-minor-mode
(equal (selected-frame) ecb-frame))
(if (and (ecb-compilation-buffer-p (ad-get-arg 0))
(equal (ecb-compile-window-state) 'visible))
(pop-to-buffer (ad-get-arg 0))
(let ((ecb-compilation-buffer-names nil)
(ecb-compilation-major-modes nil)
(ecb-compilation-predicates nil))
(ecb-with-ecb-advice 'one-window-p 'around
ad-do-it)))
ad-do-it))
所以我就把你那个直接加到最后了
一梦三年,
松风依旧,
萝月何曾老.


灵幽听微, 谁观玉颜?
灼灼春华, 绿叶含丹.
yupeng820921
帖子: 94
注册时间: 2009-02-25 19:44

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#11

帖子 yupeng820921 » 2009-04-27 10:32

yjcong 写了:
鼠标左键单击“*preview*" buffer可以把该定义所在的文件打开到另一个buffer。
实现不了。

在/usr/share/emacs/site-lisp/ecb/ecb-compilation.el中和ecb-compilation-buffer-name有关的只有
(if (and ecb-minor-mode
(equal (selected-frame) ecb-frame))
(if (and (ecb-compilation-buffer-p (ad-get-arg 0))
(equal (ecb-compile-window-state) 'visible))
(pop-to-buffer (ad-get-arg 0))
(let ((ecb-compilation-buffer-names nil)
(ecb-compilation-major-modes nil)
(ecb-compilation-predicates nil))
(ecb-with-ecb-advice 'one-window-p 'around
ad-do-it)))
ad-do-it))
所以我就把你那个直接加到最后了


哦,这么奇怪?

你用的是xemacs吗?ecb的版本是多少?

我用的ecb是2.33beta2,大约2个月前从cvs checkout的。我在我的ecb中似乎倒没有找到你贴出来的那段代码。

等我晚上再从cvs checkout一版ecb出来试试。
头像
yjcong
帖子: 2470
注册时间: 2006-02-28 3:11

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#12

帖子 yjcong » 2009-04-27 10:40

2.32-1

xemacs和emacs是有很多不同的。有的emacs配置文件在xemacs里不起作用
;;; ecb-compatibility.el --- ECB-compatibility for other packages

;; Copyright (C) 2000 - 2005 Jesper Nordenberg,
;; Klaus Berndl,
;; Kevin A. Burton,
;; Free Software Foundation, Inc.

;; Author: Klaus Berndl <klaus.berndl@sdm.de>
;; Maintainer: Klaus Berndl <klaus.berndl@sdm.de>
;; Kevin A. Burton <burton@openprivacy.org>
;; Keywords: browser, code, programming, tools
;; Created: 2004

;; This program is free software; you can redistribute it and/or modify it under
;; the terms of the GNU General Public License as published by the Free Software
;; Foundation; either version 2, or (at your option) any later version.

;; This program is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
;; details.

;; You should have received a copy of the GNU General Public License along with
;; GNU Emacs; see the file COPYING. If not, write to the Free Software
;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

;; $Id: ecb-compatibility.el,v 1.6 2005/03/30 12:50:55 berndl Exp $

;;; Commentary:
;;
;; Contains compatibility-code for other-packages.
;;
;; Whenever commands of other packages are not fully compatible with ECB then
;; this library should contain the necessary code to make it fully compatible
;; - or at least working acceptable.
;;
;; This file is part of the ECB package which can be found at:
;; http://ecb.sourceforge.net

(eval-when-compile
(require 'silentcomp))


(require 'ecb-util)
(require 'ecb-layout)

;; To add compatibilty code for packages just do:
;;
;; 1. Add the needed advice(s) to `ecb-compatibility-advices'
;; 2. Add the advice-code below.
;;
;; All advices of `ecb-compatibility-advices' will be autom. enabled when ECB
;; starts and autom. disabled when ECB shuts down. No advice is enabled just
;; by loading the ECB-library!

(defvar ecb-compatibility-advices '((bs-show . before)
(Electric-pop-up-window . around)
(electric-command-history . before)
(electric-buffer-list . before)
(electric-buffer-list . after))
"Contains all advices needed for package-compatibility.")

(defadvice bs-show (before ecb)
"Ensures `bs-show' works well when called from another window as an
edit-window. Does nothing if called in another frame as the `ecb-frame'."
(when (equal (selected-frame) ecb-frame)
(unless (ecb-point-in-edit-window)
(ecb-select-edit-window))
;; now we handle if bs-show should always display in the compile-window
(let ((my-bs-buffer (get-buffer-create "*buffer-selection*")))
;; ecb-compilation-buffer-p needs a living buffer!
(when (and (ecb-compilation-buffer-p my-bs-buffer)
ecb-compile-window-height)
(ecb-with-adviced-functions
(display-buffer (buffer-name my-bs-buffer)))))))

(defadvice Electric-pop-up-window (around ecb)
"Ensures that the electric-* commands \(e.g. `electric-buffer-list') work
well with ECB. If BUFFER is a \"compilation-buffer\" in the sense of
`ecb-compilation-buffer-p' then BUFFER will be displayed in the compile-window
of ECB - if there is any. If the compile-window is temporally hidden then the
BUFFER is displayed in an edit-window!"
(if (and ecb-minor-mode
(equal (selected-frame) ecb-frame))
(if (and (ecb-compilation-buffer-p (ad-get-arg 0))
(equal (ecb-compile-window-state) 'visible))
(pop-to-buffer (ad-get-arg 0))
(let ((ecb-compilation-buffer-names nil)
(ecb-compilation-major-modes nil)
(ecb-compilation-predicates nil))
(ecb-with-ecb-advice 'one-window-p 'around
ad-do-it)))
ad-do-it))

(defadvice electric-command-history (before ecb)
"Ensures that the electric-* commands work well with ECB."
(when (and ecb-minor-mode
(equal (selected-frame) ecb-frame)
(ecb-point-in-dedicated-special-buffer))
(ecb-select-edit-window)))

(defadvice electric-buffer-list (before ecb)
"Ensures that the electric-* commands work well with ECB."
(when (and ecb-minor-mode
(equal (selected-frame) ecb-frame)
(ecb-point-in-dedicated-special-buffer))
(ecb-select-edit-window)))

(defadvice electric-buffer-list (after ecb)
"Ensures that the electric-* commands work well with ECB."
(if (get-buffer "*Buffer List*")
(bury-buffer (get-buffer "*Buffer List*"))))

;; we disable the advices at load-time
(ecb-disable-advices ecb-compatibility-advices)

(silentcomp-provide 'ecb-compatibility)

;;; ecb-compatibility.el ends here
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defcustom ecb-compilation-buffer-names `(("*Calculator*" . nil)
("*vc*" . nil)
("*vc-diff*" . nil)
("*preview*" . nil)
,(if ecb-running-xemacs
'("\\*Apropos.*\\*" . t)
'("*Apropos*" . nil))
("*Occur*" . nil)
("*shell*" . nil)
("\\*[cC]ompilation.*\\*" . t)
("\\*i?grep.*\\*" . t)
("*JDEE Compile Server*" . nil)
,(if ecb-running-xemacs
'("\\*Help.*\\*" . t)
'("*Help*" . nil))
("*Completions*" . nil)
("*Backtrace*" . nil)
("*Compile-log*" . nil)
("*bsh*" . nil)
(,(if ecb-running-xemacs
" *Message-Log*"
"*Messages*") . nil))
"*Additional buffer names that should be displayed in the compile-window.
Buffer names can either be defined as strings or as regexps. If the
buffer-name of a buffer matches one of the defined string or regexp then it
will be displayed in the compile-window of ECB even if `compilation-buffer-p'
says nil for this buffer.

It is not recommended to add the name of eshell-buffers to this list because
ECB already handles the eshell-integration as best as possible.

See also the options `ecb-compilation-major-modes' and
`ecb-compilation-predicates'."
:group 'ecb-compilation
:group 'ecb-most-important
:type '(repeat (cons (string :tag "Buffer name")
(boolean :tag "Handled as regexp"))))
一梦三年,
松风依旧,
萝月何曾老.


灵幽听微, 谁观玉颜?
灼灼春华, 绿叶含丹.
yupeng820921
帖子: 94
注册时间: 2009-02-25 19:44

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#13

帖子 yupeng820921 » 2009-04-27 13:45

我现在还没有环境check out最新的ecb,不过应该可以确定就是ecb版本的问题。

老版本的ecb里面没有用到ecb-compilation-buffer-names这个东西。

emacs和xemacs是有很多不同,不过根据我所看到的代码,在ecb中,这些不同都是通过(if ecb-running-xemacs ... ) 这样的语句区分的,ecb的源代码肯定是同一套,所以更新一下ecb应该就可以找到“ecb-compilation-buffer-names”这个东西。另外,你也可以在你的ecb中搜索一下有没有"*vc-diff*"之类的字符串,我估计ecb中总得有一个列表定义哪些buffer属于compilation buffer,在那个buffer列表里添加上"*preview*"就可以了。

对了,顺便问一句,你用的ecb版本有没有打什么patch啊?在emacs中,用老版本的ecb会有method buffer过一会儿就消失的问题的,要更新到新版本或者打上patch才能解决,我用的那个2.33beta2版本都算是老的,我是打的patch解决的,在xemacs中没有这个问题吗?
头像
yjcong
帖子: 2470
注册时间: 2006-02-28 3:11

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#14

帖子 yjcong » 2009-04-27 13:56

xemacs没遇到过。但说来惭愧, 还不会打补丁。

那个找到了, 在ecb-file-browser.el里。其实我用xemacs主要是写很长的latex,编程是副业
(tree-buffer-defpopup-command ecb-file-popup-vc-diff
"Diff file against last version in repository."
(let ((file (tree-node->data node)))
(find-file file)
(vc-diff nil)))
一梦三年,
松风依旧,
萝月何曾老.


灵幽听微, 谁观玉颜?
灼灼春华, 绿叶含丹.
yupeng820921
帖子: 94
注册时间: 2009-02-25 19:44

Re: 在emacs中使用像source insight 一样的函数预览窗口(升级版)

#15

帖子 yupeng820921 » 2009-04-27 21:33

yjcong 写了:xemacs没遇到过。但说来惭愧, 还不会打补丁。

那个找到了, 在ecb-file-browser.el里。其实我用xemacs主要是写很长的latex,编程是副业
(tree-buffer-defpopup-command ecb-file-popup-vc-diff
"Diff file against last version in repository."
(let ((file (tree-node->data node)))
(find-file file)
(vc-diff nil)))
恩,看起来你找的这个地方不像是complication buffer的列表。

我今天check out了最新的ecb cvs版本,可以找到ecb-compilation-buffer-names。

要不你也更新一下ecb试试吧。

安装cvs之后,打开命令行,输入以下:
cvs -d:pserver:anonymous@ecb.cvs.sourceforge.net:/cvsroot/ecb login (回车)

cvs -z3 -d:pserver:anonymous@ecb.cvs.sourceforge.net:/cvsroot/ecb co -P ecb (回车)

就可以把最新的ecb check out出来了。
回复