> F30.me

My personal place to publish… stuff.

October 2012

(oh-my-)zsh key bindings on Ubuntu 12.10

After upgrading my Ubuntu system to the 12.10 beta recently, I experienced some strange quirk in my shell related to the oh-my-zsh key bindings: The up-line-or-search feature on arrow-up (resp. down-line-or-search on arrow-down) had ceased to work. One could still browse the history using the arrow keys as that seems to be zsh’s default configuration, but the “search history for commands beginning with the first word I entered” feature didn’t work anymore.

I figured out that Ctrl+V reported the key code ^[OA for arrow-up, while the other tools I checked (namely cat and bash) still returned the ordinary ^[[A. At first I guessed that this behavior had to do with Ubuntu’s upgrade to zsh 5.0, but then some help from #zsh on freenode pointed me into the right direction:

Debian’s /etc/zsh/zshrc (and therefore Ubuntu’s as well), which is executed for every shell in addition to your personal .zshrc now contains those crucial lines:

if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then
    function zle-line-init () {
        printf '%s' ${terminfo[smkx]}
    }
    function zle-line-finish () {
        printf '%s' ${terminfo[rmkx]}
    }
    zle -N zle-line-init
    zle -N zle-line-finish
else
    # ...
fi

In general, it seems to be a good idea to put the terminal into “application mode” before executing zle, at least you can find code like that in some other zshrcs as well. I still don’t entirely understand what this is about, but some information about terminal modes can be found here. What’s important to know in order to understand the above snippet is that by outputting the smkx or rmkx codes, you enable or disable application mode.

Application mode, however, uses different key codes which don’t match the hardcoded ones from oh-my-zsh. I finally solved the issue by replacing the oh-my-zsh arrow key bindings with this:

bindkey "${terminfo[kcuu1]}" up-line-or-search
bindkey "${terminfo[kcud1]}" down-line-or-search

(Debian’s /etc/zshrc conveniently stores the codes in an associative array called keys, but I didn’t wanna rely on that.)

There might be more key bindings which are affected from the problem, but I only noticed it for the arrow keys in daily usage. In my opionion it is bad style to use hardcoded key codes for the bindings in the first place and this is something that should be fixed by oh-my-zsh. I’m even a bit surprised why I couldn’t already find a patch or at least a bug report – if I manage to find enough time, I’ll definitely do that.

Update: Heres’s my pull request targeting the problem. What I wasn’t aware of (even though there’s a comment describing it right above the relevant lines), is that the reason to enable application mode at all is making use of terminfo. Ironically enough, you have to make sure application mode is really active (using some code similar to the above one), if you want to fix the problem that it causes. After all, however, you get a cleaner and more portable configuration.

4 Responses