Working Faster in Emacs by Reading the "Future"

There are a number of times when using Emacs that a command asks for an input string—e.g. a search string—and offers an intelligent default value you can accept simply by hitting RET. That’s fantastic when the default is exactly what you want, but what about when it’s almost what you want? Do you really have to manually type out the whole string? This is Emacs after all!

(I seem to run into this situation most often when looking to do a project-wide search for a symbol via something like projectile-ag; the function conveniently offers the symbol at point as a default search string, but it often has an aliased namespace prepended that I want to remove in case that namespace prefix isn’t present in all files).

The solution to this problem is pretty simple: press M-n and the default string will be inserted into the minibuffer for you to edit.

But the rationale behind this is a bit more interesting:

Experienced Emacsers will know that you can use M-p and M-n to navigate to the previous and next items in the minibuffer’s history, but it turns out that the minibuffer supports a concept called “future history” such that you can navigate forward in history (from the “present”) to access certain pre-loaded items that the author of the command deemed could be useful selections for the user. From the info page describing read-from-minibuffer:

The argument DEFAULT specifies default values to make available through the history commands. It should be a string, a list of strings, or ‘nil’. The string or strings become the minibuffer’s “future history”, available to the user with ‘M-n’.

So the model for minibuffer reads is essentially:

           ^
Actual     |
History    | M-p
           |
Prompt: ---+---
           | RET  (default is 1st future history item)
Future     | M-n
History    |
           v

I think this a pretty clever mechanism for adding extra utility to commands without any major changes to the model.

From the Elisp (i.e. Emacs development) side, we can use this easily from either read-from-minibuffer, or the higher-level minibuffer tools like read-string with something like:

(read-from-minibuffer "Favorite food: " nil nil nil nil '("Ice Cream" "Cake"))
(read-string "Favorite food: " nil nil "Sushi")

The second case demonstrates that a single default can be passed as a string, but it still appears as a (sole) item in the future history list.

So don’t forget to read the future when Emacsing! 🔮 I foresee it saving you time.