开发工具 请教一个 Emacs 的问题.

zw963 · 2012年04月01日 · 最后由 zw963 回复于 2018年11月11日 · 5561 次阅读

@hbin, @doitian,

还有其他喜欢 Emacs 的朋友们~~

嗨~ 我问下,你们是否知道在 Emacs 下,有直接可以访问光标处方法定义的源码的办法。

就类似于查看一个 lisp 函数定义那么方便。

以上问题基本上解决,通过 etags 的方式。

新加一个问题:

谁知道如何实现类似于 Emacs 中以下功能: 在一个 (require 'abced) 语句中,当光标在 abcde 上面时,按下 C-x C-f, 直接打开目标源码文件。

我理解错了么? 不是 ctags?

#1 楼 @jinleileiking

ctags 怎么用呢?能讲一下么?

#1 楼 @jinleileiking

你就跟我说一下,如何把 Ruby 的内核和标准库的方法,创建一个 tag 呢?

#2 楼 @zw963 -_-# vim 简单。emacs 据我所只,肯定是能用 ctags 的,我没玩过 emacs,不知道啊。

vim 很简单:

  • 编译 vim 时带着 ctags 选项一般的发行版都带着,我也不确定有没有这个选项
  • emerge ctagsapt-get ctags
  • 在你项目的根目录执行 ctags -R 生成 tags 文件
  • 配置 vimrc,见我的github, 我实在是懒
  • 进入 vim,确保目录正确
  • 到你的方法处,猛按ctrl+]. f__k it.
  • okay,已经进去了..

另外唠叨一句:ctags 对 ruby 的解释不好,有的 tag 生成的不对,ctags 也很久没维护了,希望社区能找到一个替代品。曾经看了ctags的代码想改的...But

#4 楼 @jinleileiking

已经找到途径了。通过 etags,一个 ctags 的变种。

不过还没解决。在研究。

#5 楼 @zw963 我记得 ctags 是支持 emacs 的。

kao!!

Both forms of the program understand the syntax of C, Objective C, C++, Java, Fortran, Ada, Cobol, Erlang, Forth, HTML, LaTeX, EmacsLisp/Common Lisp, Lua, Makefile, Pascal, Perl, PHP, Postscript, Python, Prolog, Scheme and most assembler-like syntaxes.

唯独没有 Ruby.

#8 楼 @jinleileiking

是的。只好通过 REGEXP 来实现了。

新加了一个问题。还望有知道的朋友分享下~

如果是 elisp 的话,那么有 find-function 命令可以跳转到相应的函数定义的位置

如果是 Ruby 的话我也想知道……

@zw963

第一个问题:请参见 GNU Global,比 ctags 和 etags 都好用,貌似对 Ruby 也是支持的(不确定) 第二个问题:请搜索 Emacs find file at point,或者自己写一个也不是难事

ctags 支持 ruby 的。我一般这样生成 TAGS:ctags -e --Ruby-kinds=-f --tag-relative -o %s -R %s

  1. ffap 可以抽取当前光标处所在文件名进行查找
  2. 有 helm/anything 的话,helm-at-point在加前缀的时候会抽取出当前光标所在文件名开始搜索,也就是 C-u helm-at-point

#13 楼 @yedingding -f 不就不 index methods 了吗?

匿名 #17 2012年04月01日

#13 楼 @yedingding 我一般直接就 ctags -R --languages=ruby

#12 楼 @liuw

谢谢回复。

  1. 我已經用正则和 etags 实现了。暂时还是够用为主吧。有空的时候观摩下 GNU Global. 听名字就很大气...
  2. 貌似也不是那么容易的事儿。Ruby 库可不是像 Lisp 似的,加个 el 扩展名就完事儿

#14 楼 @doitian ffap 是什么?是不是你指的是 ffip ? find-file-in-project. 具体怎么用呢?按那个键会抽取光标处的文件名?

#19 楼 @zw963 没绑定的,可以 bind 到 C-x f,直接 M-x ffap 也可以,Emacs 自带的 find file at point。我是 helm-sources 里加的全是找文件和 buffer 的 sources,所以一般我都用 C-u helm-at-point

@zw963

ffap is the abbreviation of find-file-at-point.

Check it out with 'C-h f find-file-at-point' . It's already built-in.

(Sorry, I don't have Chinese input method on my desktop machine)

自己写的话,(ffap-string-at-point) 可以用这个函数抽出当前位置的文件名

lisp 里 ffap 快狠准,估计 ruby 只能找当前目录下的文件玩玩

#21 楼 @liuw 谢谢,知道了。事实上 ido-find-file 用的就是 find-file-at-point. 这个对于 Lisp 很好使。Ruby 就基本上废了. 我就是想找一个 Ruby 的替代品. #22 楼 @doitian 自己写要处理的问题太多了。我 Lisp 目前太差了。写起来太费劲儿。

#17 楼 @ruchee

我试了下你的办法可用。

该死的 linux. 我查了 man 帮助,etags,和 ctags,用的一个,帮助里根本没有提支持 Ruby 语言. 而且我用 etags 试了,的确不支持。 而且也根本没有提--language-force 参数。(以前那个 language 参数提示作废)

ctags 的格式我和生成的 etags 格式不一样的。我怀疑是否能用。我还是用我那个 etags 好了。

Ruby 标准库我生成了下。竟然 15000+ 个 defun 定义。太庞大了

#25 楼 @zw963 用 Exuberant Ctags

#26 楼 @doitian

The etags program is used to create a tag table file, in a format understood by emacs(1); the ctags program is used to create a similar table in a format understood by vi(1).

这是我的 man 帮助的内容。我没试过,不过 Emacs 要能支持 ctags, 还要 etags 干嘛?

用 etags 生成的是以下格式:和 ctags 不一样的,.

/root/.rvm/rubies/ruby-1.9.2-p318/lib/ruby/1.9.1/sync.rb,630 def Err.Fail(*opt)54,1007 def UnknownLocker.Fail(th)60,1156 def LockModeFailer.Fail(mode)67,1298 def Sync_m.define_aliases(cl)76,1412 def Sync_m.append_features(cl)88,1719 def Sync_m.extend_object(obj)96,1893 def sync_extend101,1962 def sync_locked?115,2264 def sync_shared?119,2310 def sync_exclusive?123,2356 def sync_try_lock(mode = EX)128,2426 def sync_lock(m = EX)136,2579 def sync_unlock(m = EX)157,3000 def sync_synchronize(mode = EX)222,4362 def sync_inspect239,4674 def sync_initialize246,4933 def initialize(*args)257,5145 def sync_try_lock_sub(m)262,5206

匿名 #28 2012年04月01日

#25 楼 @zw963 你执行 ctags --list-languages 就知道支持哪些语言了。。我困惑的是,怎么那么多人以为 ctags 只支持 C/C++ 呢

#1 楼 @jinleileiking #12 楼 @liuw #14 楼 @doitian #17 楼 @ruchee

感谢楼上几位。NND. 最开始学习 linux 的时候,知道 ctags, etags 这些东西。只是那时候懵懵懂懂的,不太明白干嘛用的。N 久了。这么好的东西我都忘个一干二净了。现在终于把 etags 派上用场了。

不过,我只是通过 re 实现 etags 下的 Ruby 函数定义的搜索,这我已经很满足了。

我想问下,如果是原生支持的语言的话,例如 C, 除了搜素函数定义,还搜索哈玩意儿?

#24 楼 @zw963

Hmm... I'm confused. What do you want? What's the point in bringing up ido-find-file?

I presume you want to open file that doesn't reside in the same directory, right? Then you can hack it a bit: http://stackoverflow.com/questions/259354/goto-file-in-emacs

BTW I just looked it up a bit, GNU Global doesn't provide official Ruby support (yet).

However one guy wrote an article on this, which dated back to 2008: http://simple-and-basic.com/2008/10/using-rtags-ang-gtags-for-coding-ruby.html

#30 楼 @liuw

嗨~~, 我标题帖子有提到:

在一个 (require 'abced) 语句中,当光标在 abcde 上面时,按下 C-x C-f, 直接打开目标源码文件。

因为我使用 ido-mode, 所以 C-x C-f 绑定为 ido-find-file, 他会检测当前光标所在是否满足一个文件路径, 满足就提示打开。它内部调用的就是你说的 ffap.

其实我希望实现的是: 有关 Ruby 特别定制的,在 require "abcde", 语句那里,也可以通过 C-x C-f 打开。

#30 楼 @liuw

哥们儿,你的 E 文水平,小弟佩服的五体投地~~

我不知道 emacs,但是 vim 不能叫支持 ctags,而是支持 TAGS 文件,换句话,你只要在项目下有这个文件,vim 就可以从这个文件里找到这个定义

下面找到了 ctags 的一段说明,果然 emacs 也是支持的:

http://ctags.sourceforge.net/ctags.html#HOW TO USE WITH GNU EMACS

Emacs will, by default, expect a tag file by the name "TAGS" in the current directory. Once the tag file is built, the following commands exercise the tag indexing feature: M-x visit−tags−table FILE Select the tag file, "FILE", to use. M-. [TAG] Find the first definition of TAG. The default tag is the identifier under the cursor. M-* Pop back to where you previously invoked "M-.". C-u M-. Find the next definition for the last tag.

所以用 ctags 就可以了,我一般是这样用:

sudo apt-get install exuberant-ctags

ctags-exuberant -a -e -f TAGS --tag-relative -R app lib vendor /opt/ruby-enterprise/lib/ruby/gems/1.8/gemsm

#34 楼 @azhao

M-. [TAG] Find the first definition of TAG. The default tag is the identifier under the cursor. M-* Pop back to where you previously invoked "M-.". C-u M-. Find the next definition for the last tag.

这个帖子是错误的,误导了很多人。

M-. 在 Emacs-lisp 模式下,是 find-function-at-point. 根据英文的描述,它指的是 find-tag 命令. M-* 这个命令跟 find-tag 没有关系的。它只跟 tags-search 或 tags-query-replace 有关

不信你试试。看看是不是我说的那样。

#35 楼 @azhao

怎么你的 ctags 能同时传递多个目录作为参数??

知道了。Ctags -R 表示递归查找,etags 表示--no-regex

#32 楼 @zw963 ido 用 ffap 的前提是ido-use-filename-at-point(或者ido-use-url-at-point)为 non-nil.

抱歉六年半后,挖了我自己坟贴 ......, 前几天在网上找到了一段 10 年前的 blog 文章,发现了解决类似问题的 lisp 代码,然后今天改了改,现在工作的蛮好,有用到的请自取吧。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号