Skip to content

Instantly share code, notes, and snippets.

@greghendershott
Last active August 21, 2020 14:28
Show Gist options
  • Save greghendershott/dbdd6f1a7b30ef9766943bbf7ab55a71 to your computer and use it in GitHub Desktop.
Save greghendershott/dbdd6f1a7b30ef9766943bbf7ab55a71 to your computer and use it in GitHub Desktop.

Let's say you want to run Emacs for Linux under Windows Subsystem for Linux. The following is what I have been trying, for about 48 hours as I write this. So, take this with a grain of salt. It is not meant to be a polished or comprehensive tutorial.

Do a vanilla WSL install

  • Install Windows Subsystem for Linux itself.

  • Install a distro from the Microsoft store, e.g. Ubuntu.

Install Emacs for Linux

Install Emacs as you normally would on Linux. For example sudo apt install emacs. (Or use a custom PPA. Or build from source. Keep in mind that it's a real GNU/Linux userland with the same binaries and tools.)

I have my ~/.emacs.d in Git. So in WSL I git cloned it.

I use use-package, so the first run will install Emacs packages.

At this point you can fire up Emacs and run it in non-GUI mode. If that's enough for you, skip the next section.

Install and configure an X server for Windows.

  • Download and install some X server. I used Cygwin X. It is free and the performance seems fine.

  • Set the X server to connect via TCP, with an auth cookie. (AFAIK using a Unix domain socket won't work from WSL to Windows.)

  • The Windows X server will create an .Xauthority in your Windows home dir, and write a cookie to it.

    But Emacs for Linux will look for it in your WSL home dir, create a soft link:

ln -s /mnt/c/Users/<win-user-name>/.Xauthority /home/<linux-user-name>/.Xauthority

Now you can do:

emacs --display :0.0

and it should work. Instead of --display, you can add DISPLAY=:0.0 to your Linux environment.

Workflow

At this point you can use Emacs to edit files under /mnt/c i.e. "normal Windows files".

You can M-x shell and get the distro's shell. You can run tools, including Git.

In my experience Magit will be noticeably faster than when using Emacs for Windows and Git for Windows. IIUC, this is because Magit does many (call-process "git" ...). On Win32, starting a process is relatively heavy. But on Unixes it is realtively fast. With WSL, the Linux distro userspace is talking directly the Windows NT kernel, bypassing the Win32 subsystem.

Caveats/Tips/Notes

  • I've only been trying this for about 48 hours.

  • Keep in mind the standard warning from Microsoft. It is fine for Linux programs to modify files under /mnt/c. But don't do the reverse. Don't try to find the Linux filesystem under AppData, and use Windows programs to try to modify those files.

  • To be safe, for now I'm regarding the Linux file system as a space mostly for tools and tool configuration files. Otherwise, I'm keeping source code under /mnt/c, i.e. keeping it as "normal Windows files".

  • You can run the Linux version of compilers, use them from Emacs, and everything is simple. In other words you can use this as a lighter, nicer alternative to running Linux in a VM.

  • But what if you also want to run Windows compilers, too? e.g. What if you're using Windows to be able to test how your programs build and run on Windows, and just want a nicer Emacs/Git/Magit experience? You can definitely do that, too.

    One gotcha is that fancier Emacs prog modes may get confused about Windows vs. WSL pathnames. So if you're running Windows Racket.exe in Linux Emacs, and it reports errors as c:\path\to\foo.rkt:4:2, then Emacs' next-error probably won't find them. From its point of view, the file is really /mnt/c/path/to/foo.rkt. It's not so much the slashes; Emacs is usually pretty flexible/tolerant about that. It's the paths being rooted differently.

    There is a wslpath tool available in the Linux shell. wslpath -u c:\path\to\foo.rkt returns /mnt/c/path/to/foo.rkt, and wslpath -w /mnt/c/path/to/foo.rkt returns c:\path\to\foo.rkt. I hacked racket-mode to add a pair of customizations, racket-path-from-emacs-to-racket-function and racket-path-from-racket-to-emacs-function, which default to #'identity but can be used to supply functions that call wslpath. And I used those in a few places, such as where racket-mode tells the Racket back end what program to run, and in the Racket REPL's compilation-mode-regexp-alist. (Tip: The FILE element in the alist can be, instead of a number, a function of no args. The function can do something like return (list (funcall racket-path-from-racket-to-emacs-function (match-string 1))) -- in other words, it can adjust the pathname on the fly.)

    In short, it is generally no problem to run Windows tools from Emacs Linux, using M-x shell. Basic things will work. Some conveniences like next-error might need a helping hand.

Misc

  • On Windows 10, with any flavor of Emacs (even native Emacs for Windows) you may notice that C-) does nothing. Which sucks if you like to slurp s-expression using paredit or smartparens. It turns out this is due to C-S being bound to a language input setting, which you can disable.
@greghendershott
Copy link
Author

UPDATE I originally tried this on 1803. 1809 was a big regression. I can't really recommend this.

In fact, on the laptop that came with 1809, last night I spent < 1 hour installing Ubuntu 18.04.2. Not dual-boot -- just blowing away Windows 10. This is my first time attempting to install Linux on bare laptop hardware. Just like for this person, it went much more smoothly than I expected. The Emacs experience on Linux is, needless to say, wonderful. So many things just-work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment