Friday, July 31, 2009

Fixing Alt Arrow Key Bindings in tcsh

It took a while, but the IT department at work finally got around to upgrading the OS on my workstation to Ubuntu 8.04 LTS. It's a bit outdated when compared to my home setup (Debian/Squeeze), but familiarity goes a long way - it feels better. There were some kinks that had to be ironed out, but for the most part it was a pretty smooth transition.

One problem that irritated me was shell key bindings. I'm used to move the cursor a word at a time with <ALT> <LEFT> / <RIGHT> - and was horrified to find out that these key binding stopped working.

I contemplated the differences between my home setup and my work setup, and figured that it had to be the shell. You see, we use tcsh as the default shell at work, instead of bash - I have no idea why, but it's the standard here.

I tried the alt-arrow keys in bash and found that they work nicely. bash uses readline, so its key bindings are set in ~/.inputrc. tcsh, on the other hand, seems to be handling key bindings on its own.

With my hunch verified, all that needed to be done was add the missing key binding to my ~/.tcshrc. I already had the following:
bindkey -k up history-search-backward
bindkey -k down history-search-forward

so I guessed I could use alt-right as a key name, like this:
bindkey -k alt-right forward-word

but this only earned me an error message.

I did the sensible thing and asked a coworker, who had Ubuntu installed on his workstation before me, and he told me that he had the same problem and that there was a fix - "just add the following magic to your ~/.tcshrc":
bindkey '\e[1;3C' forward-word 
bindkey '\e[1;3D' backward-word

I did as I was told, and it didn't work. Well, not quite - it did fix the key binding under konsole, which is the terminal emulator that most of my coworkers use, but not under rxvt-unicode - the terminal emulator that I use.

So I did the other sensible thing, and searched the Net for a solution. I hit a message on the screen mailing list, which got me on the right track.

Basically all I had to do was run cat at the console, hit alt-arrow keys, record the strings that are echoed back, and use these as the key combinations to bind. Here's what I got:
bindkey '^[^[[C' forward-word
bindkey '^[^[[D' backward-word

Thank you Lazyweb.


  1. Now if you could find a way to fix filename completion to occasionally send SIGABRT to the process attempting it, we'd be all set.

  2. ...I meant to say "so that it doesn't occasionally send SIGABRT".

  3. The closest description I could find with a quick search is Ubuntu bug #219527. But my workstation doesn't seem to be affected by it.