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.