How to Keyboard with Mac and ZSH

How to Keyboard with Mac and ZSH

I've been a longtime admirer of zsh, but never found time to leave the comfortable bash world. On my personal machine, I took the leap to install macOS Big Sur, and switched my shell to ZSH, only to realize I no longer could function efficiently in the terminal.

Thank You Apple 😏

There's nothing quite so humiliating and disorienting as learning a new shell. Much of the keyboard muscle memory I have built up over years was rendered useless.

I just had to fix my environment, so I figured I'd save it here for future reference.

iTerm2 Keybindings

I'm not even going to bother with the built-in macOS Terminal. My key bindings are generally compatible with the old-school bash version of Terminal. But the new Terminal has the same handicaps.

There are a bunch of hex codes and control codes that need to be sent for iTerm to work just how I like it.

Instead of describing them all, just download my iTerm2 key mappings here: https://drive.google.com/file/d/1EI8a1pl5h2-vmCHbJWuoi4I2VbPlOwJd/view?usp=sharing

Go to Profiles → Open Profiles → (select your profile) → Edit Profiles... → Keys → Presets... dropdown → Import...

There may be some unnecessary bindings in there I've accumulated.

ZSH Config

I had to make some additions to the .zshrc file to get the shell to act more like bash. Maybe one day I can eliminate these crutches but it's not today.

Word Characters

By default, zsh word-based movements include / as a word character. In bash, when working with paths it is very handy to treat path components as words. Update the $WORDCHARS variable by adding this to your .zshrc file.

export WORDCHARS='*?_-.[]~=&;!#$%^(){}<>';

ZSH Key Bindings

These bindings map the keys for jumping to the start and end of the line.

bindkey '^[[H' beginning-of-line
bindkey '^[[F' end-of-line

Disable Autocomplete

A really cool but annoying feature of zsh is that when using tab completion, when tab is pressed multiple times, the first option is selected. The bash behavior is to cycle through options so my tab finger is always happy to rapid-fire as needed to find the right thing. In zsh this is counter-productive.

To fix this, disable the menu complete. The tab behavior is now sane, and allows for unambiguous selections to tab complete, but it will not select the first option when there are multiple potential options. This still isn't exactly like bash, I have to now type another letter as opposed to just rapidly hitting tab, but this is at least something I can retrain myself to do without major hiccups or stutters in the terminal.

setopt noautomenu
setopt nomenucomplete

Mac Compatible Shell Bindings

With everything configured as describe above, this is a summary of the movements I regularly use to navigate my shell. Quickly navigating the command line saves a ton of time and keeps focus on the task at hand.

These bindings match macOS key bindings so you can use most of these in any text editing situation. Having the same Terminal bindings as OS bindings makes it even easier to have an uninterrupted keyboard flow.

Keys Description
⌘ ← Move to begining of line
⌘ → Move to the end of line
⌥ ← Move to the previous word
⌥ → Move to the next word
⌥ Backspace Delete previous word
⌘ Backspace Delete entire line
Shift PgUp Scroll up
Shift PgDn Scroll down

More Mac Keyboard Tips

Here are some other critical key bindings which make life easier by keeping your hands on the keyboard as much as possible. This is for those who struggle to feel in control of their desktop, or find themselves scrambling to find windows and tabs.

Show Comments