Wandering Thoughts archives

2023-10-06

Understanding the orderless package for GNU Emacs

Orderless is a popular Emacs package for modifying how minibuffer completion works. It gets mentioned frequently when people talk about their Emacs customizations or put together 'bedrock' setups and, driven by that, I gave it a try. My initial reactions weren't particularly positive; I didn't like the changes to default completion behavior (which I turn out to be very accustomed to) and I didn't understand when and why I'd want its style of completion, or even really what it was. However, for various reasons I kept it around and now I feel like I've figured out what's going on and tamed it into something I want. So I'm writing it all down while I still remember it.

Put simply, orderless lets you match (select) completions using multiple words (components) that can occur in any order in the completions you want. A 'word' can match in several ways; by default orderless tries to match each word as a regular expression or a literal substring. So if you start M-x and type 'insta pack', it will match 'package-install' and 'package-reinstall', among others.

You don't need orderless to match a single word as a substring of the completions, for example if you want to be able to type 'Mess' to select the '*Messages*' buffer (without having to put the '*' at the front). This single substring match is the standard Emacs 'substring' completion style, which is already enabled for various types of completions in a stock Emacs configuration (including buffer completions; see the value of 'completion-category-defaults').

For orderless completion to be really useful, you need to be matching things that contain multiple 'words' where either you don't remember what order the words are in or you want to skip over bits in the middle. The names of Emacs (lisp) functions and variables are a great example, since they're usually long names formed as 'word1-word2-word3', and while you may remember some words that are (probably) in them, you may not remember all of the words or what the order is. This multi-word, any order matching also makes orderless a nice way to explore what's available for some combination of keywords, like looking for M-x commands using 'region' and 'shell' (which will turn up shell-command-on-region).

Unfortunately, orderless completion doesn't work very well with hierarchical completion, such as file names and anything like them, because at each step through the hierarchy you're usually only completing something that's a single word.

(One personally relevant example of this is MH-E mail folder names, which are completed component by component; if you want to select a folder called '+admin/vendors/cables', you must complete each piece one by one. MH-E could get a complete list of all mail folders and let you complete everything up front, which would let orderless jump directly to things deep in your folder hierarchy, but sadly MH-E doesn't (and I don't feel like rewriting its folder completion system).)

If you put orderless first in your completion styles, as its documentation suggests, it will basically take over your minibuffer completions. As a side effect, it will probably make TAB useless in the minibuffer and just generally mess up completion behavior that your reflexes may be very used to. If you don't want to completely change your reflexes, the simple thing to do is to put orderless last, making it a fallback:

(use-package orderless
  :custom
  (completion-styles '(basic partial-completion orderless))
 )

Orderless as a fallback completion that's only tried last has been pretty pleasant and inoffensive so far. I'm not sure I'd go as far as saying that it's a modest package, but at least I didn't wind up with too much configuration for it (that use-package stanza above is my full current settings).

PS: if you want to readily explore what you're getting with orderless completion, you probably want to look into something that shows you completion results all the time, on the fly, like vertico. However, vertico is definitely not a modest package and took me significant tweaking and configuration before I was happy with it.

As far as I can tell, orderless works fine on its own, although you'll probably be hitting TAB TAB a lot to show the full set of current completions and you won't get interactive feedback while typing your multiple words.

programming/EmacsUnderstandingOrderless written at 23:11:58; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.