Monday, November 02, 2009

cmd-key-happy -- swap cmd and alt keys in Terminal.app

Swap cmd and alt (or command and option) keys in Mac OS X using cmd-key-happy

This program allows you to swap the command and alt (or option) keys in any application, but in particular Terminal.app. This can be extremely handy when ssh'ing into other UN*X boxes and running "emacs -nw". It also allows you to have the traditional readline navigation work properly when using Bash (i.e., alt-backspace, alt-f, alt-b, etc).

The decision to swap the keys is based on a customizable script (Lua) and this also allows you to exclude certain key combinations per application. For example, "cmd-tab" is an exclusion in my Lua script regardless of which application is running; I still want this key combination to cycle the active set of applications.

The motivation for this program was the many years of hitting alt-<something> in Linux only to find that it does not generate the same behaviour in Terminal.app. Having the ability to run "emacs -nw" from within Terminal.app is now useable!

29 comments:

Brian said...

I was able to successfully install and use cmd-key-happy. I am indeed happy. I have noticed that the remapping stops working sporadically. My suspicion is that it is related to sleep states as it usually happens after a period of inactivity with my MacBook Pro. If you have any tips on how to fix, I'd be happy to test. Where's the donate link :)

--b

aim said...

Yes, I see the same thing on my Macbook Pro when waking from sleep.

I'll take a look at fixing this; I currently use:

launchctl stop com.frobware.cmd-key-happy
launchctl start com.frobware.cmd-key-happy

to get things going again.

chrismealy said...

This is fantastic! Thank you!

Arthur P. said...

At least in Mac OS 10.6.2, /usr/local/bin/ does not already exist when "make install" is called, causing the executable itself to be named "/usr/local/bin".

I expect this is a two-line fix to the Makefile; alternatively, I'd suggest prepending a note to INSTALL saying "make sure /usr/local/bin exists and that System Preferences -> Universal Access -> Enable access for assistive devices is turned ON."

aim said...

INSTALL and Makefile updated accordingly.

Andreas said...

Sounds like exactly what I've been looking for!
Unfortunately I wasn't able to get it running on Snow Leopard.

Whenever I start or restart cmd-key-happy I get the following in the syslog:

Mar 1 17:49:00 hostname cmd-key-happy[34022]: enable access for assistive devices
Mar 1 17:49:00 hostname com.frobware.cmd-key-happy[34022]: cmd-key-happy[34022]: enable access for assistive devices
Mar 1 17:49:00 hostname com.apple.launchd.peruser.501[186] (com.frobware.cmd-key-happy[34022]): Exited with exit code: 1

No error message is given on the command-line:

$ cmd-key-happy
cmd-key-happy[34036]: enable access for assistive devices
$ echo $?
1

Downloaded the source code just today. Could someone help me with debugging?

Thanks,
Andreas

intractable said...

I just discovered this after being frustrated about this for the better part of 2-3 years. I agree with the initial poster: where's the donate link?

And thanks muchly -- this has indeed made my emacs -nw on remote machines gloriously more tolerable :P

Cheers.

Michael Scheibe said...

With Snow Leopard Terminal.app can do this natively.
Terminal.app > Preferences > Settings > Keyboard > Use option as meta key

Alt-b and alt-f works for me now.

aim said...

Yes, alt-f works, but I want this to happen on the cmd key. In Terminal/Bash you cannot do cmd-f and get forward-word to work. You have to use alt-f. With cmd-key-happy you can swap those keys around so a cmd-f becomes alt-f.

Brian said...

I added:

launchctl stop
launchctl start

to my .bashrc to see if that would help me from losing my mappings too quickly.

Interestingly, it gave me a reproducible case. If I launch two windows with the keyboard, at the third launch the cmd-key-happy exits.

Launchctl tells me that it exits with zero status. No message is left in syslog.

Since it is exiting with zero status, it is possible that we could use the KeepAlive feature in the plist file and have launchd relaunch the program upon exit.

This would give us a more formal workaround for the occasional time when cmd-key-happy exits.

I'll play around with this and see if I can get it to work.

Brian said...
This comment has been removed by the author.
Brian said...

So far, it appears to work.

I added

<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<true/>
</dict>

to the plist file and reinstalled.

I had to reboot because for some reason the unload did not work.

However, after reboot, it appears to be working correctly.

I'll give this a week to see if it holds up.

Stunt said...

So happy I found this! Just wanted to confirm for anyone else that this works still great on Leopard. I tested on 10.5.8.

Also, if you copy the Terminal settings, this will work perfectly for iTerm too.

Once again, thanks!

Anonymous said...

this is brilliant -- thanks for doing this.

another game said...

ah... took a year to find this

i was using emacs-nw
with command-option switched

but command-tab wouldn't work.

now i can do normal editing in emacs and command-tab also works!

adamdoupe said...

This made my day.

Thanks so much for this awesome app!

Anonymous said...

In case anyone else hits this problem when trying to build the source code...

I got this CMake error:

The C compiler "/Developer/usr/bin/gcc" is not able to compile a simple test program.
[...]
ld: library not found for -lcrt1.10.6.o

The cause might be that you ran the cmake command with the wrong arguments, or no arguments at all. You should run it with the following arguments. And case is important:

cmake -G Xcode

If you really, really don't want to use XCode to build the project then running this command before running cmake might help:

export LIBRARY_PATH=/Developer/SDKs/MacOSX10.6.sdk/usr/lib

Good luck!

aim said...

The best thing to do is use the Makefile and not CMake.

NoFixedAbode said...

Thanks for this utility!

I've tried to add iTerm 2 by adding the following line to cmd-key-happy.lua in the 'apps' array:

["iTerm 2"] = { exclude = {} },

but it doesn't seem to work. Is that the proper Lua syntax for specifying keys w/ spaces? I tried a bunch of other methods but this was the first that actually compiled.

Pietagina said...

Hullo I have installed this and it seems to partially work on snow leopard however the reason for installing it was to have both meta-key alt-x in emacs -nw but also have # alt-3. With cmd-key-happy running it switches alt-x to cmd-x as advertised but alt-3 and cmd-3 do nothing so i still have no #. What have I done wrong.

Failing that how do I uninstall it if I dont want it as it launches at boot now everytime?

Anonymous said...

Thank you! You've saved me much aggravation with this utility!

aim said...

I recently added an `uninstall' rule which should remove the binary and the plist file - its that files that causes the program to start automatically launch when you login.

Anonymous said...

This is the best utility ever. Seriously, put a donate button up and I will send you some money!

Alex said...

As a note, the arrow keys are denoted as:
right
left
up
down

In my case, this was useful because I have them mapped to switch between (desktop) spaces. So I added:

global_excludes = Set{
"cmd-right",
"cmd-left",
"cmd-down",
"cmd-up"}

and everything worked great!

P.S. - These are defined in the escapeCharGrp1 in cmd-key-happy.m

Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...

thank you! this is the best thing on the internet. (for at least the last 37 ms.)

piper said...

Hi guys,

any experience with OSX 10.8.3 ? I've successfully builded the binary, turned on "Enable access for assistive devices", checked "Use option as meta
key" in terminal preferences and then fired this utility with

./cmd-key-happy -d -f example-rcfile.lua

but it don't swap alt/cmd in my case. No diagnostic found in system log. Any tips ?

Unknown said...

Thank you so much! This is exactly what I have been looking for.