sacha chua :: living an awesome life


Subscribe!
E-mail Feed reader

Eclipse to Emacs: Navigating your source tree

Two other things I like about the Eclipse development environment are the ability to jump to a function definition and the ability to open any resource in the workspace. Fortunately, these shortcuts are easy to duplicate in Emacs.

Exuberant Ctags is a utility that builds an index of the function definitions in your source code. You can use this index to jump to any function definition using editors such as vi or emacs. To index your Drupal source code, for example, go to the root of your source directory and use a command like this:

find . -name \*.module -o -name \*.php -o -name \*.inc -o -name \*.install -o -name \*.engine -o -name \*.profile | etags -l php -

To use this index in Emacs, add the following code to your ~/.emacs, changing drupal-project-path as necessary:

(defvar drupal-project-path "~/proj/example" "*Base path for your project")

(require 'etags)
(setq tags-file-name (expand-file-name "TAGS" drupal-project-path))

Evaluate the code. You can then use M-. (find-tag) to jump to the declaration of a function in your project.

To open any resource in your source tree with a few keystrokes, index the files with filecache and use ido to open the file. Ido is well worth learning how to use. Here’s the code I use, taken almost directly from the filecache documentation:

(require 'filecache)
(require 'ido)
(defun file-cache-ido-find-file (file)
  "Using ido, interactively open file from file cache'.
First select a file, matched using ido-switch-buffer against the contents
in `file-cache-alist'. If the file exist in more than one
directory, select directory. Lastly the file is opened."
  (interactive (list (file-cache-ido-read "File: "
                                          (mapcar
                                           (lambda (x)
                                             (car x))
                                           file-cache-alist))))
  (let* ((record (assoc file file-cache-alist)))
    (find-file
     (expand-file-name
      file
      (if (= (length record) 2)
          (car (cdr record))
        (file-cache-ido-read
         (format "Find %s in dir: " file) (cdr record)))))))

(defun file-cache-ido-read (prompt choices)
  (let ((ido-make-buffer-list-hook
	 (lambda ()
	   (setq ido-temp-list choices))))
    (ido-read-buffer prompt)))

(ido-mode t)
;; Change this to filter out your version control files
(add-to-list 'file-cache-filter-regexps "\\.svn-base$")
(if drupal-project-path
    (file-cache-add-directory-using-find drupal-project-path))

(global-set-key (kbd "ESC ESC f") 'file-cache-ido-find-file)

This turns ESC ESC f into a handy shortcut for finding files anywhere in your project tree. Read the source code (ido.el) for more information on ido shortcuts.

Good luck and have fun!

(UPDATE: Added “.” to the find command – two people suggested it! =) )
(UPDATE: Forced etags to detect files as php and added .engine and .profile to the list of extensions)
(UPDATE: Added version control filter for file-cache)

So-soHmmGoodGreatAwesome! (No Ratings Yet)
Loading ... Loading ...
Save to - del.icio.us - Digg it - reddit - StumbleUpon -

27 Responses to “Eclipse to Emacs: Navigating your source tree”

  1. it’s probably just a typo, but you should have a pathname before the expression in ‘find’. e.g. ‘find ~/ -name …’

  2. It is all right, thank you, but how do I navigate back and forth?
    Say I was in file BfromA.cpp then went to spec of the class in BfromA.hpp by find-tag
    and then to the file A.hpp to the father class, again by find-tag.

    Is there any way to go “back” to BfromA.cpp without mentioning it explicitly – just go “back”
    and then again go “forward” to A.hpp explicitly?

    Thank you very much

  3. @Nick

    When you go to the other file after using the find-tag, you end up switching buffers. This means the last buffer is simply a C-x b RET away. Unfortunately, it also means that if you go to another definition, then you have to return to the buffer more explicitly.

    With that said, hopefully Sacha will have a good answer to that question :)

    FWIW, I have just started using the etags and find-tag feature, and it is very helpful. It was also extremely fast adding the tag index, which was a pleasant surprise.

    Great post!

  4. The same can be achieved with my vps package

    http://ozymandias.dk/emacs/emacs.html#vps

  5. @Eric
    Hi!
    I know this way, but it falls into “explicit” navigation.
    I think there should be some way to hook find-tag with emacs bookmarks and then
    it is possible to navigate through them.

  6. After find-tag you can go back with pop-tag-mark bound to M-* usually. I don’t know of a way to go forwards again other than by M-. on the same keyword. I use etags-select-find-tag-at-point instead of find-tag:
    ___
    M-. runs the command etags-select-find-tag-at-point
    which is an interactive Lisp function in `etags-select.el’.
    It is bound to M-..
    (etags-select-find-tag-at-point)

    Do a find-tag-at-point, and display all exact matches. If only one match is
    found, see the `etags-select-no-select-for-one-match’ variable to decide what
    to do.
    ___

    I also find tags-apropos quite useful.

  7. I use M-. with interactive arg (C-u) to find next tag and `pop-tag-mark’ (bound to M-* by default) to get back to previous tag.

  8. You can go back with M-*. There is no forward command, so you use M-. go to the same function again.

  9. The path is not required with the find command on GNU/Linux, I think – or at least the one that I’ve got installed. =) I should put that in, though, as other systems require it. Thanks!

  10. Hi Sacha,

    I am absolutely certain that any geek reading this will be using some form of version control in their source trees…. at work I use Subversion and to exclude all the junk svn files ‘find’ will pull in I added the following before the file-cache find command:

    (add-to-list ‘file-cache-filter-regexps “\\.svn-base$”)

    Regards

    Arjen

  11. Arjen: Thanks for pointing that out! I ended up adding that line to my ~/.emacs before I read your comment. Much nicer. Now if I can just get it to sort by frequency of access… ;)

  12. I tried the command:
    find -name \*.module -o -name \*.php -o -name \*.inc -o -name \*.install | etags -

    and I get an error:
    etags: Unknown option -

    Was the command truncated from the post or something? what’s the parameter?

    Is there a way to automate the etags generation from within emacs so I don’t have to remember this command every time I start a project?

  13. There is actually an error in the post.

    find needs a first argument that says where to look for these files:

    find -name \*.module -o -name \*.php -o -name \*.inc -o -name \*.install | etags -

    should be

    find . -name \*.module -o -name \*.php -o -name \*.inc -o -name \*.install | etags -

    notice the dot between find and the -name,

  14. <laugh> Okay, everyone else has a find that requires a path… Updated!

  15. There’s an etags that comes with Emacs, and there’s an etags which comes with Exuberant Ctags. I’m using the one from Exuberant CTags. Don’t know if that makes a difference…

  16. You can also enable flymake to check your PHP source code for errors as you type it, I posted the elisp code for that on my blog:

    http://blog.nethazard.net/2008/07/31/php-syntax-check-as-you-type-with-emacs/

  17. fixed it!
    In my version of exhuberant Ctags i would have to use the command like this:

    find . -name \*.module -o -name \*.php -o -name \*.inc -o -name \*.install | etags -L -

  18. With the Exuberant CTags from Sourceforge, I just found out that you should probably make it etags -l php -. =)

  19. Totally! Next, I’m going to go into more detail about Xdebug and GEBEN…

  20. With the Exuberant CTags from the Ubuntu Hardy repositories the command is:
    etags –language-force=php -L -

  21. [...] she could be more productive in Emacs then in Eclipse in her current project, read about it here, here and [...]

  22. etags isn’t finding my class methods in my php files. Do you have a regex that you use to find the public class methods?

  23. I’ve got a problem: I use php 5 and I think etags supports only php4. Bad :(

  24. Hi,

    I following the above instruction.
    But when I enable filecache adn ido in .emacs, my emacs goes to 100% for > 5 minutes, for some reason. I have to kill the email using System monitor.

    Can you please tell em how to fix it? I am running on ubuntu.

  25. There is some confusion between etags and http://ctags.sourceforge.net/

    or at least they are not the same in Debian.

    I generate my tags using something like

    SRC=~/.emacs.d
    cd $SRC
    ctags-exuberant -e –recurse=yes –links=yes –verbose=no

    No need for find.

    And unlike etags it supports recursion in the one command.

  26. Do you think that you might have some symbolic links that cause a loop? That’s the first thing I think of…

  27. [...] Chua wrote a post about navigating your source tree using ido and filecache. I’m not sure what additional benefits filecache offers over vanilla ido as ido finds files [...]

Discussion Area - Leave a Comment

Please comment as you, not your organization.





On This Day...

  • 2009: Lotus Notes mail merge from a Microsoft Excel spreadsheet — Mwahahahahaha! I’ve been looking for ways to recognize people’s voluntary contributions to community discussions. E-mailed thanks are great because people can [...]
  • 2008: Morning pages from Ottawa — In one of her books, Julia Cameron suggested writing morning pages as a way to get one’s creative juices flowing [...]
  • 2008: Emacs: Keyboard shortcuts for navigating code — One of the lines on my list of things I can do in order to make progress on my book [...]
  • 2007: A Midsummer Night’s Dream — Old readers of this blog would know how special A Midsummer Night’s Dream is to me, of all Shakespeare’s plays. [...]
  • 2007: I’m going to run away and join the circus — When I thought about what I would do if I had all the money I wanted, I realized that trying out [...]
  • 2006: Creative Thursday: Conference commando! — On the way to jazz choir practice, I thought about what I like creating and when people have called me creative. [...]
  • 2006: Planning my week with zones — I think IBM’s Think!Fridays are a great idea. It’s like zoning a day for a particular purpose. I tend to treat [...]
  • 2006: I heart ultraportables! — The power adapter for my Fujitsu Lifebook P1110 gave up two days ago. With the funny way my life works, an [...]
  • 2006: IBM CASCON 2006: Social discovery and conferences — Another thing I want to build for IBM CASCON 2006 is an easy way to create an OPML file for conference [...]
  • 2006: IBM CASCON 2006 and conference backchannels — I got so carried away making lunch that I nearly missed the planning conference call for IBM CASCON 2006’s social [...]
  • 2006: Enterprise 2.0 definition from Andrew McAfee — Via Ross Mayfield comes Andrew McAfee’s description of Enterprise 2.0: / Optional Free of up-front workflow Egalitarian, or indifferent to formal organizational identities Accepting of [...]
  • 2006: Secret knocks — Now that’s a cool application of technology. Seen on Slashdot: “Knock” Some Sense Into Your Linux Laptop describes how to [...]
  • 2006: Speaking of costumes… — Photo taken by Matthew Burpee I have no problems turning up at a high-tech geek get-together about Enterprise 2.0 wearing a [...]
  • 2006: I like someone — I like someone. There, I’ve said it. I probably shouldn’t go into much detail over here, but you can check out [...]
  • 2005: Wahoo! Bikergal! — I’ve signed up with BikeShare, a Community Bicycle Network program that’s like a library for bikes. They plan to turn Toronto into a [...]
  • 2005: Bank account needs social insurance number needs employment contract — Sorting out my finances is harder than I thought. My funding won’t kick in until September, although they’re still paying 12 [...]
  • 2004: Cognitive overload — http://icl-server.ucsd.edu/~kirsh/Articles/Overload/published.html Discovered via http://del.icio.us . I like both much.
  • 2004: What do I really want to focus on for graduate studies? — I think there’s some promise in this planner.el thing. I’m intrigued by the fact that we can make personal information managers [...]
  • 2004: Migration guide for Microsoft Windows to Linux — http://www.linuxgazette.com/node/view/9187 http://www.kbst.bund.de/Anlage304428/Migration_Guide.pdf William Villanueva said: The German Government, specifically the “Bundesministerium des Inneren” (Ministry of Interior Affairs) has published a 444 page Migration-Guide that covers [...]
  • 2003: Configuring SSH behind a proxy — http://www.webweavertech.com/ovidiu/weblog/archives/000017.html
  • 2003: The importance of mentoring — http://www.artima.com/weblogs/viewpost.jsp?thread=7600