Sharing the Mac Clipboard with Emacs

Posted by Doug Thu, 08 Nov 2007 02:09:00 GMT

While I’m sharing emacs hacks, I finally got around to researching this and/or figuring it out. I almost always run emacs inside the terminal in a “no window” mode. It’s pretty natural for me to use M-w to copy something from emacs and then try to Cmd-V it in another Terminal window or likewise Cmd-C something in Terminal and then try paste it into emacs with C-y. Until now, I haven’t known how to share the clipboard with emacs.

(defun copy-from-osx ()
  (shell-command-to-string "pbpaste"))

(defun paste-to-osx (text &optional push)
  (let ((process-connection-type nil)) 
      (let ((proc (start-process "pbcopy" "*Messages*" "pbcopy")))
        (process-send-string proc text)
        (process-send-eof proc))))

(setq interprogram-cut-function 'paste-to-osx)
(setq interprogram-paste-function 'copy-from-osx)

This takes advantage of the pbcopy and pbpaste command line programs to access the clipboard and offers them up as elisp method for emacs’ interprogram-*-functions. Easy, peasy, pumkin weasy.

I need to give some props to Mark Aufflick for his post on Automatic Copy from X11 App to Mac OS Clipboard. My paste-to-osx is pretty much a straight rip from him.

Posted in ,  | Tags , , , ,  | no comments

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

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 ... 9

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