Navigating Your Projects in Emacs

Posted by Doug Wed, 07 Nov 2007 16:04:00 GMT

One of the things that’s really nice about TextMate is the Cmd-T navigation of files in your project. It pops up this little dialog with fancy pattern matching input to select one of the files in your project and then jumps to that file. There’s a similar command once your in a file to jump to symbols in that file. I’ve tried a couple things to achieve that behavior in emacs that I’d like to talk about.

The first thing I tried was a method called find-file-in-project. It was originally implemented by Phil Hagelberg as part of his “Another Ruby on Rails Mode” (arorem) and then also ported over to the current Rinari Is Not a Rails IDE. Basically, it indexes all the files in a “project” and then provides a nice interactive completing read to switch between them. It basically works just like Cmd-T in TextMat. I did quite a bit of work optimizing the completing read so that it would behave nicely. The problem is that emacs is slow to index the files in your project.

What I’m using now is the tried and true find-tag method which is part of etags.el. ETags depends on an external TAGS file as an index of all the symbols in your project. When you invoke find-tag (by default bound to M-.) it prompts you with completing read for the symbol to find. It then jumps directly to the file and location where that symbol is defined. It’s basically combining the find-file-in-project with find-symbol-in-buffer. It’s also very, very fast.

As an added bonus, you can use tags-search to search through your project finding places that tag is used. This is similar to TextMate’s slowly grep all the files and render a buffer with those results in it, but much faster.

The bad news is you have to manually build the TAGS file periodically. Emacs is pretty good about continuing to work when you’ve made modifications to the files, but if you add new methods, new files, or refactor significantly where thing are located then it gets confused. When that happens, simply rebuild the TAGS file.

Jim Weirich gave me a nice little rake task to do the job:

module Tags
  RUBY_FILES = FileList['**/*.rb'].exclude("pkg")
end

namespace "tags" do
  task :emacs => Tags::RUBY_FILES do
    puts "Making Emacs TAGS file"
    sh "xctags -e #{Tags::RUBY_FILES}", :verbose => false
  end
end

task :tags => ["tags:emacs"]

Just put that in lib/tasks/tags.rake and then run rake tags:emacs when you invoke find-tag and it can’t find it. That shouldn’t happen very often. I’ve found it’s also very fast to build the TAGS file. I might consider putting that tags task as part of the normal run tests task, but I’m not sure that’s necessary.

The other catch here is that the rake task above calls out the exuberant ctags rather than the ctags that comes with emacs. The exuberant ctags knows how to parse ruby files whereas the ctags that comes with emacs can’t.

I’ve installed exuberant ctags from MacPorts. It is xctags even though MacPorts doesn’t install it that way. So (for better or worse) I’ve renamed the ctags files installed with ports to xctags. This also gets around the conflict that MacPorts thinks there is between the ctags installed with emacs and the exuberant ctags.

Give this a spin and let me know what you think. I’ve found it to be very accurate and very fast.

Posted in , , , ,  | Tags , , , , ,  | 4 comments

Remote Pair Programming

Posted by Doug Tue, 09 Oct 2007 13:47:00 GMT

I mentioned in my post the other day about remote pair programming and someone called me out on it via email. Since I spend probably between 40 – 60% of my work time remote pair programming I thought I’d give some of my experiences.

First, some background. I’ve been moonlighting as a freelance web developer for a lot of years. I work with David Minor at Sus 4. He and I have done remote pair programming on almost all of our projects for the last four years. I also telecommute for my day job into blah blah blah (lawyers made me change this). I travel to the headquarters in VA once a month or so, but work from home the other three or four weeks. Probably half to three-quarters of my programming tasks at blah blah blah (lawyers made me change this) I pair with another developer. There are several different people that I’ve paired with regularly over the almost two years I’ve been there. Finally, I’ve talked a lot about remote pair programming at the Cincinnati Agile Round Table. From their Jim Weirich has picked up on my techniques while doing remote pairing at Edge Case.

What I’m trying to say here is that I have done a lot of remote pair programming over the years and I’ve tried a lot of different techniques. What I’m about to describe here is tried, tested, and proved.

Being on a Mac, I have paid licenses of both TextMate and SubethaEdit. They are both fine editors. I think I prefer TextMat over Subetha simply because I think TM handles projects better. However, I do think Subetha’s networking and multi-user support is really cool. The problem is with Rails projects I always end up with lots and lots of files open. Subetha doesn’t make it easy enough to share the files by default or for the remote guy to join their shared files by default. Plus, with TDD you have to have some way for both partners to see the test output.

While talking about things that don’t work… there’s just not enough bandwidth for VNC. I’ve done all I know to do to optimize it: drop the number of colors, change backgrounds to solid colors, muck with compression algorithms. I just can’t quite squeeze enough bandwidth out so that it feels interactive for both people.

So what does work? Welcome to the past. What I’ve found is that gnu screen running inside a terminal is the most bandwidth efficient, highly interactive, flexible multi-user environment. One person hosts, the other connects via ssh and joins the hosts screen session. For those who’ve never used screen, both users connected see exactly the same thing. Both users keyboards have simultaneous control of the terminal. Combine this with a good voice/video channel with Skype or iChat and it’s nearly as good as actually sitting next to someone.

Inside of screen you can have multiple tabs/windows. What I typically do is designate my first window to run emacs. This is my “IDE”. We do all text editing from inside there. I have another window designated for running tests (although sometimes I run tests from inside emacs). I have another window designated for the mysql prompt. Another is for tailing log files and another for running the server. Screen saves the history (I typically set it to something ridiculously large). Both people can see when you scroll through the buffer history. Both people can see all the data.

I’ve kinda glossed over the use of emacs here. I’ve also done remote pairing with vi (well, vim anyway). The point is that it helps a great deal if you’re using an editor that both people understand. I pair with a guy at work that only begrudgingly uses emacs. It’s not nearly as much fun for him. I’ve also paired with folks who aren’t comfortable with any terminal based editor. That’s no fun either.

Like pair programming when you’re actually together, there are a number of things to consider. Editor environments is one of them. Remote pair programming seems to heighten or exacerbate all the issues with local pair programming. Your communication issues are bigger. You really have to make a point to tell each other what you’re doing. Talk, talk, talk! A definite anti-pattern is one of the people in the pair going off to work on solutions locally on their own computer while the other person can’t see what’s going on. Do all work in the screen session. Make sure that both people can see everything that’s going on. Related to this, it’s hard for one person to “see” when the other is distracted. If one person is checking email while the other is trying to stay on task that’s no good.

The good news is that remote pair programming can work. I find actually pair programming in person to be very fulfilling, fun, and exciting. Remote pair programming isn’t as good as actually being together in the same room. However, it’s a very good substitute when the commute cost are high. If you’re the kind of person that doesn’t really dig pair programming in general, odds are you’ll find remote pair programming to be even less attractive than actual pairing.

I’ll also mention I know one guy (whom I respect a lot) who’s big on pair programming, but just can’t get in the groove of remote pair programming. I suspect his problem is lack of familiarity with the editor, but there may be other philosophical issues as well.

All that said, I don’t find running emacs inside a screen to be some “least common denominator”. In fact, I do all of my development this way—even when I’m not pairing. Lately I’ve been running multiple screen sessions on my box; one for each project I’ve got going. My “state” is always right where I left off. When I switch from independent work to pairing, it’s easy for someone to simply join my screen and we can get started. I’ll stop here and not get too carried away with singing emacs’ praises. That’ll be good info for another post…

Before I close out, it occurs to me that screen can be pretty ugly with zero config. I’ll go ahead an post my hard status config. This dresses things up quite a bit and makes it a lot easier to use. Put these lines in ~/.screenrc:

hardstatus on
hardstatus alwayslastline
hardstatus string "%{rk}%H %{gk}%c %{yk}%M%d %{wk}%?%-Lw%?%{bw}%n*%f%t%?(%u)%?%{wk}%?%+Lw%?" 

Posted in , , , , ,  | Tags , , , , , ,  | 11 comments

Resizing Your Terminal

Posted by Doug Fri, 05 Oct 2007 12:24:00 GMT

I thought I’d go ahead and publish this because I found it useful (if ugly). I do a lot of remote pair programming where my partner and I share a multi-user screen session inside a terminal. It’s very important that both partners have the same number of columns and rows visible. Otherwise, whoever is smaller isn’t going to see everything the other person sees and stuff jumps around and it’s generally annoying.

So, the first thing that happens when you start a remote pairing session is you negotiate screen size. I have my Apple Terminal.app set to show the screen size in the title bar as something like 105×54 or 94×71 or whatever. So when my partner says, “I can do 120×62 as my maximum size” I have to click and drag my Terminal window until my size matches. No more!

As I said above, this is pretty ugly but it works. This shell script makes a one line applescript call through osascript to tell the Terminal what size to make the window. I put it in a shell script like this to simplify calling. I started with a straight up applescript, but it was ugly to call it from the command line. So I converted it to what you see here:

#!/bin/sh /usr/bin/osascript -e 'tell application "Terminal"' -e "tell front window" -e "set the number of rows to $2" -e "set the number of columns to $1" -e "end tell" -e "end tell"

You can invoke it by simply saying:

$ resize_terminal 94 71

and the front most Terminal window (likely the one you’re typing in) will resize to 94 rows tall by 71 columns wide.

Posted in ,  | Tags , , ,  | 2 comments

Older posts: 1 2 3 4 5 ... 241

Copyright 2001 - 2005 by Lathi.net and Doug Alcorn

Creative Commons, Some Rights Reserved Ruby on Rails Developer Powered by Debian GNU/Linux Powered by Typo