Power up your locate command
02 Jul 2015locate
I'm sure many people know that Emacs comes with a locate
command. This command, if you're on a Linux system, will find all
files on your system that match a particular pattern. The advantage of
locate
over find
when searching the whole system, is that it is
much faster, since it uses a pre-computed database. This database is
updated periodically, you can force an update with:
sudo updatedb
Of course find
is faster if you need to search only a specific
directory instead of the whole system, but sometimes you just don't
know that directory.
counsel-locate
Dynamic
The way locate
works it that it asks you for a query, which is
glob-based instead of regex-based, and then prints the results to a
static buffer.
On the other hand, counsel-locate
is dynamic: each time you input a
new character a new locate
query is ran, and the old one is
terminated. On my system, it takes around 2 seconds for a query to
complete, so it requires a bit of patience.
Regex-based
I like regex way more than globs for some reason. Here's the command
called for the input mp3$
:
locate -i --regex mp3$
Of course, the standard ivy-mode
method is used to build the regex from a list of space separated
words. So the input fleet mp3$
will result in:
locate -i --regex \\(fleet\\).*?\\(mp3$\\)
You could go your own way and update the regex matcher to be
ivy--regex-fuzzy
, which results in:
locate -i --regex f.*l.*e.*e.*t.* .*m.*p.*3$
But I think less matches is usually better than more matches.
Multi-exit
This is just the coolest feature. Basically, for each file you locate, you can easily:
- Open it in Emacs (default).
- Open it with
xdg-open
, so that PDF files are forwarded toevince
and MP3 files are forwarded torhythmbox
etc. - Open it in
dired
.
Here's an example of how to do it. First I call counsel-locate
,
which I like to bind to C-x l. Then I enter emacs pdf$
and wait around 2 seconds for the 248 results to come up. Then I
scroll to the 18th result and press C-o to open up the
hydra-based option panel:
The last column (Action) is newer than others. As you can see, it has 3 exit points, which I can scroll with w and s. And currently I'm on the default exit point, which would open the file in Emacs.
For the next screenshot:
- I pressed s twice to change the action to
dired
. - I pressed c to make the current action execute each time a new candidate is selected.
So now, I could just scroll through all my directories on my system that contain PDF files related to Emacs by just holding j.
A similar thing can be done for music tracks:
- C-x l
dire mp3$
to get the list of all Dire Straits tracks on my system. - C-o s to switch the action from "open in Emacs" to "xdg-open".
- From here, I could open one track after another by pressing C-M-n repeatedly. Or I can press c and then j repeatedly.
I've been experimenting with opening EPS and PDF files in quick
succession. It's still a work in progress, since I need to use a special
wmctrl
script to prevent the Emacs window from losing focus each
time a new Evince instance is opened.
Outro
You can check out the new feature by installing counsel
from
MELPA. It will automatically fetch ivy-mode
as well. When you enable
ivy-mode
, besides doing all your completion, it will also remap
switch-to-buffer
to ivy-switch-buffer
. That command also has a
multi-exit: pressing C-o sd instead of C-m will
kill the selected buffer instead of switching to it. It's a very
minor optimization: instead of C-m C-x k you press C-o
sd, however you could e.g. use C-o scjjjj to kill
five buffers at once.
While the idea of multi-exits is powerful, it's hard to find places to
use it efficiently. I think counsel-locate
is a nice place for it,
although it could work without it:
- Find file in Emacs with C-m in the completion interface.
- Call
dired-jump
with C-x C-j. - Type ! and
xdg-open
RET. - Select and kill the unneeded file with C-x k.
I hope you see now why I prefer C-o sd.