90 lines
7.5 KiB
Plaintext
90 lines
7.5 KiB
Plaintext
<p>My Emacs tweaking tends to go in waves. I keep an eye on the <a href="https://reddit.com/r/emacs">Emacs subreddit</a> and
|
|
the Doom Discord channel on a fairly regular basis, but I try not to jump on
|
|
every cool new package I see discussed there. Every now and again though, I see
|
|
something interesting which coincides with an itch to tinker with Emacs, and
|
|
away I go… This time, it was reading discussions about a constellation of
|
|
relatively new packages concerned with incrementally narrowing lists (and other
|
|
related functions) that caught my eye. This sounds very niche, but for many
|
|
people (me included) being presented with a list of things and being able to
|
|
type to incrementally narrow the list and then select something is a core part
|
|
of the Emacs UI. Since I use Doom, and it offers you an easy way to choose
|
|
either <a href="https://github.com/abo-abo/swiper">Ivy</a> or <a href="https://github.com/emacs-helm/helm">Helm</a>, I had been using Ivy, for the sake of easy configuration.
|
|
Both are fine packages, but having tried both, I preferred Ivy’s more minimal
|
|
interface, and the fact that it used the minibuffer rather than a buffer for
|
|
completions. However, it — and the related packages, Counsel and Swiper —
|
|
are somewhat complex and difficult to get to grips with. I was also not using
|
|
all the features that they provided, so was curious if I would enjoy using
|
|
something even simpler. That’s why I tried out <a href="https://github.com/raxod502/selectrum#why-use-selectrum">Selectrum</a>.</p>
|
|
<p>The Selectrum README page on GitHub gives an admirably thorough and clear
|
|
explanation about the niche that it is trying to fill, and how it compares to
|
|
other similar packages. What I like about it is that it tries to stick as
|
|
closely as possible to using Emacs’ standard APIs, so that once you enable it,
|
|
many standard Emacs commands (like <code>find-file</code>) automatically use Selectrum. It
|
|
also doesn’t try to do everything, so it really <em>only</em> provides incremental
|
|
narrowing, leaving sorting and filtering (and actions to operate on the selected
|
|
candidate) to other packages. This means that you have a bit more package
|
|
installation and configuration to do up front, but it also means that you can
|
|
pick and choose which elements you need and leave the others, so you end up with
|
|
a simpler system. I chose to use the following additional packages:</p>
|
|
<h3 id="prescient-dot-el">Prescient.el</h3>
|
|
<p><a href="https://github.com/raxod502/prescient.el">prescient.el</a> sorts choices in a more intelligent way, remembering your recent
|
|
selections and bubbling those to the top of the list. It also enables you to
|
|
toggle on and off different ways of matching a candidate (for example by the
|
|
initial letter of each word, or by regular expression). I have found <code>prescient</code>
|
|
to work very well in practice. It also works with Ivy and Helm and other
|
|
incremental narrowing packages, so you can use it even if you don’t use
|
|
Selectrum.</p>
|
|
<h3 id="consult">Consult</h3>
|
|
<p><a href="https://github.com/minad/consult">consult</a> works with any function that works with Emacs’ built-in <code>completing-read</code>
|
|
function (including Selectrum). It is intended as a rough replacement for
|
|
<code>counsel</code>, and provides some useful functions for searching a buffer interactively
|
|
for text, searching headlines (in Org or Markdown files, or any mode that
|
|
implements <code>outline-mode</code>). It has a very handy function <code>consult-buffer</code>. Despite
|
|
the name, it is a multi-purpose function which enables you to search and select
|
|
among a list of buffers, files and bookmarks by default, so you don’t need
|
|
separate commands to search each of those categories. If you do want to filter
|
|
the list because you know you are searching for a buffer, not a file, for
|
|
example, you can prefix your search with ‘b’ (or ‘f’ for file, or ’m’ for
|
|
bookmark). I’ve found this so handy that I have bound it to Doom’s <kbd>SPC SPC</kbd>
|
|
binding for easy access. I previously often found myself searching for a buffer
|
|
first, before realising that I needed to search for a file as the buffer
|
|
containing that file wasn’t yet open. This stops me having to think about the
|
|
distinction, but allows me to narrow the list if I am sure.</p>
|
|
<h3 id="marginalia">Marginalia</h3>
|
|
<p><a href="https://github.com/minad/marginalia/">marginalia</a> adds ‘annotations’ to some of the lists presented by Selectrum. For
|
|
example, if you use <kbd>M-x</kbd> it can add key-bindings and also docstrings to the list
|
|
of commands. Ivy did this too, and I found it extremely useful.</p>
|
|
<h3 id="embark">Embark</h3>
|
|
<p><a href="https://github.com/oantolin/embark/">embark</a> is the package I am least sure about whether I will keep, but it is
|
|
handy. It enables you to hit a key-binding when you have a candidate selected in
|
|
a list and apply some action to the item. It knows whether the item is a file or
|
|
buffer or some other item, so it presents a list of appropriate actions for
|
|
each, like opening a buffer in the other window, or renaming a file. There are
|
|
of course many other ways to achieve this in Emacs, but I find that the method
|
|
of selecting something first, then choosing how to act on it works well for me.
|
|
It is also really simple to add new actions, and I added one to jump to the
|
|
dired buffer for a file. That was as simple as the snippet below in my <kbd>config.el</kbd>
|
|
file (swap <code>use-package!</code> for <code>use-package</code> if you are not using Doom):</p>
|
|
<div class="highlight"><pre style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-emacs-lisp" data-lang="emacs-lisp">(<span style="color:#369">use-package!</span> <span style="color:#369">embark</span>
|
|
<span style="color:#038">:after</span> <span style="color:#369">selectrum</span>
|
|
<span style="color:#038">:bind</span> (<span style="color:#038">:map</span> <span style="color:#369">minibuffer-local-map</span>
|
|
(<span style="color:#d20;background-color:#fff0f0">"C-o"</span> . <span style="color:#369">embark-act</span>)
|
|
(<span style="color:#d20;background-color:#fff0f0">"C-S-o"</span> . <span style="color:#369">embark-act-noexit</span>)
|
|
<span style="color:#038">:map</span> <span style="color:#369">embark-file-map</span>
|
|
(<span style="color:#d20;background-color:#fff0f0">"j"</span> . <span style="color:#369">dired-jump</span>)))
|
|
</code></pre></div><h3 id="is-it-better-than-ivy-counsel-swiper">Is it better than Ivy/Counsel/Swiper?</h3>
|
|
<p>This setup doesn’t do anything that that Ivy and friends didn’t. It does some
|
|
things a bit differently, and in ways I prefer. The <code>consult-outline</code> command
|
|
presents Org headings in a way I find much easier to navigate, for example.
|
|
I am going to stick with these packages because I find the smaller,
|
|
more focused packages easier to understand and configure, and potentially to
|
|
extend as I need.</p>
|
|
<p>The other impressive thing about them is that the authors of each of the
|
|
packages are talking to each other and trying to make their packages as
|
|
inter-operable as possible and also as simple and discrete as possible. The
|
|
Marginalia package was extracted from the Consult and Embark packages (which are
|
|
maintained by different people), to reduce the overlap between them and ensure
|
|
that you can mix and match the different components like Lego bricks to build
|
|
your ideal setup. I find this an admirable position, which helps to keep users’
|
|
options open and improve all the tools. I’m going to watch the development of
|
|
all these packages with interest.</p> |