On Windows, running Emacs on WSL (the Windows Subsystem for Linux, or rather Linux in Windows), is faster and in my experience an altogether a better experience than running native Windows Emacs.

However, you will need to do some tweaking to use it to its maximum potential, some of which I have written about before.

In this post, I show a small but useful trick to use the brilliant and lightning fast Everything search tool to find directories and files anywhere on your Windows system whilst using helm-locate from your WSL Emacs.

On native Windows Emacs, helm-locate already uses Everything by default. On Linux, it uses the native locate tool.

The trick I propose here simply sets up a chain of shell commands that will execute Everything and convert the Windows paths to something that the Linux-compatible helm-locate can process.

Obligatory screencast gif showing Everything search in Emacs WSL through helm-locate

The first search query demonstrated in the screencast is \vxlabs.com*2020 .md. This is Everything’s syntax for “give me all .md files that are anywhere under any folder starting with vxlabs.com and containing 2020 somewhere after that”.

You can see that Everything is pretty powerful stuff.

In the second query I just did a simple search for “gut” through the PDFs in my free-form reference library. If I had wanted to find PDFs with either “gut” OR “nature” in the title, I would have done \refs gut \| nature.

Note that I had to \-escape the \ or, else it is interpreted as a shell pipe.

Aside: Making of the screencast

I used the amazing emacs-gif-screencast package by Ambrevar. This only saves out an image when you perform an Emacs command, and then compiles that sparse (relative to a fixed-FPS screencast) representation to the gif you see above.

To make this work under WSL with X410 on the Windows side, I temporarily had to start-up a window manager (invoking xfce4-session did the trick) where I usually just use the integrated “windowed apps” mode of X410. To be more specific, scrot --focused was unable to determine the focused window without a running WM.

The “trick”

Simply add the following form to your init.el. It should only activate on WSL distributions.

1
2
3
(if (and (eq system-type 'gnu/linux) (getenv "WSL_DISTRO_NAME"))
    (setq helm-locate-command
          "es.exe -n 15 %s %s | tr -d \"\r\" | xargs -r -d \"\\n\" -n 1 wslpath -u"))

This runs Everything, but limits the number of resuts to 15 (-n 15), because Windows and WSL1 is really slow at spawning processes, and we’re going to end up calling wslpath on each of the results for every iteration.

The first %s will be used by helm to set case sensitivity, and the second %s will be substituted with your search query.

We then pass all of the results through tr to remove the extraneous Windows CRs, else you’ll see ^M in Emacs. If you don’t mind these, you could remove the tr invocation.

Finally, we pass the list of Everything results to xargs, which will pass each of the Windows-style filenames into WSL-compatible Linux-style paths, so that helm get the final sanitised list.

We invoke xargs with the following switches:

  • -r: don’t run wslpath if there are 0 candidates;
  • -d: split input on newline and ignore backslashes in string;
  • -n 1: call wslpath on each candidate, not on groups as is the default.

Conclusion

With this small addition, Emacs on WSL becomes even more useful, as you could hopefully extrapolate from the screencast.

If you would like to make use of this, I recommend strongly that you read up on the Everything query syntax which can be found in the tool’s built-in help.