This is a technical article written mostly because an ethical matter[1].

Making Mutt Vi Users Friendly

The aim of these patches (tarball) is to provide an option (esc_key_aborts) for Vi users convenience.  When enabled, it replaces the abort ^G key binding for Esc.  To enable it:

:set esc_key_aborts

Caveat: as it's warned in the man page entry added by these patches, while this option is enabled, the Esc-key (Meta-key) bindings stop functioning.  This does NOT affect arrows, Home, End, PgUp, PgDown, etc. or any other of those keys that generate escape sequences in themselves.

You'll find remove.esc.bindings.rc among the files included in this tarball, that sourced from your muttrc removes all ESC+key default key bindings.  This is just to avoid the hardcoded key bindings that otherwise will still be shown in menus and help.  You may also try the vi.bindings.rc one.

Mutt maintainer disregarded these patches

In 2017 I published these patches on mut-dev mailing list[2].

You've may been wondering:

Why one key binding needs such special treatment?

Before letting suspicion and fear mislead your judgment (like it happened to those guys in mutt-dev) take some time to perform the following tests:

  1. Open Mutt (as provided, WITHOUT my patches) in a xterm.
  2. Open XTerm menu (Ctrl+left_click) and deselect “Meta Sends Escape” option.
  3. Now try any Meta+key bound command under Mutt.

    They didn't work, did they?  Now, without touching anything:
  4. Type “:” under Mutt and write:

    :set meta_key
  5. Try again some Meta+key command.

Ah, the Meta+key bindings work again!  But in the second case thanks to a mutt option intended to make Meta work on shells, terminals or ttys that aren't able to handle it by themselves (see "meta_key" option in muttrc(5).)

Now you are aware of two important details, first that the cause of the “confusion,” the infamous Meta key, has been there since ever, second that whoever wrote the meta_key option hack wasn't afraid (as the current maintainer) of touching a “low level function.”  Let's take a look to curses_lib.c:

event_t mutt_getch (void)


  if ((ch & 0x80) && option (OPTMETAKEY))
    /* send ALT-x as ESC-x */
    ch &= ~0x80;
    mutt_unget_event (ch, 0); = '\033';
    ret.op = 0;
    return ret;



This conditional is placed right above of where my patches insert the esc_key_aborts option.  Now you know that:

The Meta key is not a Mutt nor even a ncurses problem

From all keys used as modifiers (eg Ctrl, Shift, Alt,) the Meta one is a special problematic case that may need a different workaround depending on the environment you are.  If you haven't noticed this problem so far is because those who mounted the OS or the Linux distribution you've been using already took care of disguising this inconsistency with some workaround.  It seems ncurses doesn't provide an easy, clean way to make these two options live together:

Using Esc as a modifier


Using Esc to abort

It does, however, provide a way to make arrows, Home, End, PgUp, PgDown, etc. work (see “keypad” option in getch(3).)  So, again, the problematic case is the Meta key.  I'm pretty sure Mutt creators decided to hardcode ^G to abort just to avoid overcomplicated workarounds (the same did W3M ncurses web browser developers.)

But the problem doesn't end there, besides ^G Mutt developers hardcoded another 333 key bindings from which 39 are Esc prefixed (see functions.h.)  So, even if any of those “perfectionists” in mutt-dev are able to translate their wishes to code, (eg the one demanding that there must be a way to bind the abort function to any key,) unless the maintainer – “conservative” as they consider him (someone else converted Mutt in a command line version of Thunderbird while he was taking a nap :-)) – let them remove the hardcoded key bindings, the “confusion” will still be there in any or other way.

In summary, my patches are another hack like the “meta_key” one (or like the other hundred you'll surely find digging in mutt code.)  But, if you're a vi user like me, tired of hitting the Esc key by mistake again and again and “curse” curses developers mothers :-), you know these patches deserved a bit more attention.  And for all the explained above, I doubt you'll find a more clean, effective and harmless way to do it.


(1) Time ago this (personal) web site was plenty of free software related articles sharing configuration tips and shell scripting working examples for unix-like system usage and administration.  That was my little contribution.  At some point I got so tired of the level of hypocrisy, hostility, irrationality and, over all, the lack of common sense I suffered in mailing lists and forums that I decided to stop writing about it and deleting all that content from my site.

(2) The list doesn't show all the messages I sent, I ignore if because a majordomo problem or if they were deleted.  The tarball posted in this message, was a second different proposal that I decided to discard, there was another message with a tarball containing the version I'm sharing now that isn't showed in the list.  It's also important to notice that my httpd logs at that time showed just one download of the tarballs I posted in that list, from an IP located in Europe, what means it wasn't the maintainer.  That's why, as I suggest in the title, I consider that my patches were not exactly rejected but plainly ignored.

Back to “Writings”