Monday, January 19, 2009

Making the Mac OS X Terminal Hum

I recently had reason to get back to hacking at the command line again and it certainly is a pleasure. At least it was before some annoyances started to ruin my day.

The Terminal in the Mac has been improved with tabs in Leopard making the iTerm application that I used on Tiger redundant. New tabs are easily opened with Cmd-T and closed again with Cmd-W. But if I want to move between them I have to press Cmd-{ and Cmd-} which is closer to a vulcan nerve pinch than I am comfortable with.

Luckily my old license of Menu Master comes to my rescue. Menu Master ($12) is a simple tool that lets you reconfigure the menu shortcuts painlessly. So now the tabs can be easily switched with Cmd-Left and Cmd-Right as they should.

Next step is to configure bash to support my commands. My Emacs days are long gone and I don’t like to have different sets of shortcuts for the same thing in different applications. Bash uses readline for editing on the command line. I can choose between Emacs-mode and VI-mode. Emacs is still closer to my heart so I start out with this.

Aaargh!, What!, the Option key is not sent as a Meta-key and nothing works as it should. A quick look in the Terminal preference window on the Keyboard tab, shows me that I can check the use option as meta key. That sounds right…ok, here we go: Meta-delete – deletes word, Meta-. – inserts last argument of previous command, Meta-T transpose words,... Hey, we’re moving!

Ok, now I’ll just check what I did since yesterday:

git log @{yesterday}

What! No friendly at-sign appeared by the cursor, instead we move into some stupid digit-argument mode. Bastard international keyboard requiring me to use the Option key to write a simple at-sign. Ok, back to the drawing board. readline can be configured with an .inputrc file. Here’s a fix to all the number keys.

"\e1": "©"
"\e2": "@"
"\e3": "£"
"\e4": "$"
"\e5": "∞"
"\e6": "§"
"\e7": "|"
"\e8": "["
"\e9": "]"
"\e0": "≈"
"\e/": "\\"
"\e(": "{"
"\e)": "}"

While we’re editing this file we might as well add some candy to the sugar.

# Shows all files instead of beep when tab-completing
set show-all-if-ambiguous on
# Ignore case when completing, very nice!
set completion-ignore-case on

"\e[1~": beginning-of-line    # Home key
"\e[4~": end-of-line    # End key
"\e[3~": delete-char    # Delete key
"\e[5C": forward-word    # Ctrl+right 
"\e[5D": backward-word    # Ctrl+left 
"\e\e[C": forward-word    # Alt+right 
"\e\e[D": backward-word    # Alt+left
"\C-K": unix-line-discard   # Ctrl+K 
"\e\"": "@{}\e[D"     # Insert @{} move cursor into braces

Thanks to Antibaddy on Stack Overflow for help with the last one. Ok, we’re on track again. I’ll just update my .bashrc with the nice git bash extension, git-completion.bash.

mate ~/.bashrc

Sure enough, no tilde appears. I thought I could go back to .inputrc again to fix this. But the tilde is a dead key on my Swedish keyboard and it does not even seem to arrive to the Terminal when the option as meta is on. I never liked dead keys anyway but how can I get rid of them. When installing Ubuntu it is as easy as selecting a Swedish keyboard with no dead keys. Not as easy on the user friendly Mac… Can mighty Google help me. Not really. I found a couple a clues in the Apple developer notes, but it seemed to involve firing up XCode and hacking away at a brand new keyboard layout!

I’ll ask Stack Overflow again. Sure enough, a tool called Ukelele can be used. Just start it up, base your new keyboard layout on the one you are using, double-click on the dead keys, and terminate them. I got rid of all my dead keys and while I was at it I changed my umlaut (¨) to tilde (~) and vice versa. I type tilde quite often in comparison with umlaut and I’m wiling to make the mistakes I will make on a foreign keyboard.

Now I’m finally set to go. :)


Jaakko said...

Thank YOU for the ctrl-left/right codes, I have been looking for these for ages! Meta-f/meta-b really don't cut it for me because of the required "use option as meta key", which I prefer not to use.

Ed said...

YES! thanks for the alt-arrow fixes!!!!!

And the nifty show-all and completion-ignore-case!

Also very Nice!

elmimmo said...

sadly ctrl-left/right still do not work when in vim

Paul said...

Fantastic, the one thing I still hadn't gotten fixed on my OS X term, meta-arrow word-jump! YAY! The other thing, which is really annoying to enter (you apparently can't just type it), is the stuff in the terminal inspector for e.g. page up and page down so they get passed through to the term and don't just scroll the window, so you can shift-pgup/pgdn the window itself as it should be. I just keep that in a terminal config file that I keep tucked away so I can set it properly without going through all the pain of actually setting it up by hand with every new OS X install :)

Also, HAHAHAHA @ elmimmo ... works just fine in emacs, which uses readline correctly :D I used to be a serious vim user until I FINALLY took the time to learn emacs and then I never looked back :)

Anders Janmyr said...

@Paul, I'm glad it helped you, but I switched to a US keyboard with some Ukelele tweaks and I'm using vim-mode in readline now so all I use now is:

set editing-mode vi
set keymap vi-insert
set show-all-if-ambiguous on
set completion-ignore-case on