Patching "bundle open" to set your current directory

Ruby programmers need to be able to read the source code of the libraries (gems) that they use. Bundler makes it easy to load the source of a gem into your editor, with the bundle open command:

$ bundle open activerecord

It checks your $EDITOR environment variable to open the gem's code in your favourite editor.

It works great with Textmate, but (as pointed out by Ben Griffiths) when used with Vim it could be improved slightly by changing the current directory to the gem's folder before running Vim.

Inspired by Ben's shell script, I wrote a short Bash function to replace the bundle command that ships with Bundler. It's a useful technique; worth blogging about simply to point out to those who haven't dabbled in it how handy shell scripting can be...

bundle () 
    if [ "$1" == "open" ]; then
        ( cd $($(which bundle) show $*) && $EDITOR . )
        $(which bundle) $*

The function shadows the bundle command (in the event that two commands should have the same name, functions are run in preference to external scripts).

The script checks to see whether its first argument is "open". If it is, the first command is removed from the argument list (with shift) and then the real bundle program is called with $(which bundle). The $* variable contains all the arguments that were passed to the function (minus the "open" that we just shifted off the front), so it's really just calling Bundler's show command to find the path to the gem's folder.

The path is handed to cd so that we change directory, and then the editor is run in the current directory.

The brackets surrounding the cd... && $EDITOR . command run the commands in a separate process, which prevents our current shell's current directory from being changed. If we didn't do that then we'd find our current directory would be the gem's directory, after we quit our editor.

I love feedback and questions — please feel free to get in touch on Mastodon or Twitter, or leave a comment.

Published on in Vim, Ruby