Installation of Spacemacs on Windows via WSL2

A step by step guided installation tutorial with context


Updated: 2024-01-27 Sat 00:19

Take advantage of the unparalleled, extensible, and powerful text editing capabilities of GNU Emacs from within Windows OS.


1. Introduction

Is it possible to judge whether or not a piece of music is objectively good, perfect and beautiful? The word "objectively" must sound a bit old fashioned, after all, every man is doing what is right in his own eyes in these times1. But we can be reasonably certain that a song which has been well loved generation after generation has a quality absent from a yet untested, recently released album. Yes, I'm talking about Emacs here. 40 odd years is a terribly long time in the world of software. We have reason to be grateful as Spacemacs has done its part in flattening the notorious Emacs learning curve. This tutorial can be said to be directed towards non-programmers who are comfortable with computing (as this write-up originally existed as personal notes of mine). I hope you take away something useful!

Window Subsystem for Linux (WSL) runs a real Linux kernel on a lightweight Virtual Machine. Praise be to the Windows team responsible for the continued development of WSL. A couple of milestones achievements include,

2. Install WSL & Emacs

The official WSL documentation is now much more polished than when this tutorial was initially published. The following inside Windows Powershell (run as Admin) will enable WSL, Linux distributions are operating systems that use the Linux kernel. We are running a Linux operating system within a Windows operating system – shortened to subsystem if you will.

# Installs WSL and sets the default distribution to Debian.
# Use wsl --list --online to list available Linux distributions.
# See https://docs.microsoft.com/en-us/windows/wsl/install for more.
wsl --install -d Debian

Install Emacs from official Debian package distribution. Inside your WSL bash shell,

# Debian 12 stable repos have emacs 28.2. Instead of 'sudo apt install emacs',
# we use backports to get emacs 29.1
sudo apt install emacs-el/bookworm-backports
# Why not emacs-pgtk? See https://github.com/microsoft/wslg/issues/294#issuecomment-1911481055
sudo apt install emacs-lucid/bookworm-backports
sudo apt install emacs/bookworm-backports

3. Install Spacemacs

Enter the following in your WSL terminal to install Spacemacs. We do this in two instructions sent to the terminal. The first is to download a version-control software called Git. Think of Git as allowing multiple developers (writers) to collaborate on the creation of software (documents) in a distributed manner. The next instruction is to download a copy of Spacemacs onto our local computer.

sudo apt install git
git clone https://github.com/syl20bnr/spacemacs ~/.emacs.d

Now for the moment of truth. Launch Spacemacs by the following command in the WSL terminal.

emacs &

On the initial startup, you will be presented with a few choices. Pick "All aboard the evil…..Vim" and then "Full Installation" for the second choice. Rest assured, you will be able to change the first option later on in your dotspacemacs (~/.spacemacs) file and if you are a beginner, the full installation is preferred over the base installation. In the first initial startup, you will have to wait for all the MELPA packages to download and install. MELPA is the package manager for all Emacs packages. After the download is completed, you will have successfully installed Spacemacs. Launching Spacemacs is now as simple as using the shortcut Windows has automatically created for Emacs in your Windows start menu.

3.0.1. Fixing the Font

If you get a message informing you that "adobe source code pro" cannot be found, you can install it with the following WSL bash commands2, or manually after having consulted: Fonts - Debian Wiki

#!/bin/bash
set  -euo pipefail
I1FS=$'\n\t'
mkdir -p /tmp/adodefont
cd /tmp/adodefont
wget -q --show-progress -O source-code-pro.zip https://github.com/adobe-fonts/source-code-pro/archive/2.030R-ro/1.050R-it.zip
unzip -q source-code-pro.zip -d source-code-pro
fontpath="${XDG_DATA_HOME:-$HOME/.local/share}"/fonts
mkdir -p $fontpath
cp -v source-code-pro/*/OTF/*.otf $fontpath
fc-cache -f
rm -rf source-code-pro{,.zip}

In addition, if you're running Spacemacs as a daemon, then the following fix is needed to display the correct font.

4. How WSL (Ubuntu) files are treated by Windows

DO NOT access the WSL linux files under @appdata/canonical etc. in the Windows explorer. According to the WSL developers, this is due to differences in how file metadata is implemented in Linux versus Windows. 2 methods of properly accessing your files:

  1. To access your linux files, in your WSL bash terminal enter in

    explorer.exe .
    
  2. WSL Filepath method. Location of these files is under "\\wsl$". Click on windows explorer address bar at the top to input this address.

5. Getting Comfortable with Spacemacs

A couple of first steps to get yourself grounded. Makre sure you take caution to avoid the dreaded Emacs pinkie. Repetitive strain injury and carpal tunnel are painful and debilitating. Personally, I have made the following changes to my keyboard layout to make it more ergonomic. The benefits spill over to applications outside of Emacs as well. To do so:

  1. Install Microsoft PowerToys
  2. Under the Keyboard Remapper, swap right ctrl and right alt.
  3. swap left ctrl and left alt.
  4. swap left alt (physically the left ctrl key) with the Windows key. This will retain comfortable alt-tabbing.
  5. swap esc with caps lock.

    Emacs is designed to be keyboard driven, although scrolling and mouse support works out of the box. Now let's get started.

5.1. Prerequisite: familiarity with basic vim operations

If are new or want a brushup, access the built in tutorial via "SPC h T v" in Spacemacs ("SPC h T e" for the emacs version). If you pause after hitting "SPC", you will see a popup. This package is called "emacs-which-key" and it frees you for remembering 1001 commands. Like memorizing a piano piece, you will pick up your most commonly used bindings soon enough. To extend this analogy further, Spacemacs bindings are not without reason, but are designed to be mnemonic. If you are new to vim's way of modal editing, here is some helpful reading: vi - What is your most productive shortcut with Vim? - Stack Overflow. Even more interactive vim tutorials are easily found online.

Think of Vim as a domain specific language for editing text, whereas Emacs' traditional keybindings are of a chordal nature. But Emacs is written in a dialect of LISP, a computer language uniquely suited to build domain specific languages. A marriage made in heaven as far as I'm concerned.

5.2. Watch and Learn

In terms of time efficiency, depth of content covered, and ease of understanding, nothing surpasses:Spacemacs: Installation, Configuration, and Navigation Tutorial - YouTube (20 min). I seriously and whole-heartedly recommend the rest of his videos. Definitely try following along.

Almost all configuration will be done in your ~/.spacemacs file. For a proper understanding of the ~/.spacemacs file, see Streaky Cobra's breakdown of the file. The only update to this information is the placement of custom user layers and snippets in the "private" directory of the ~/.emacs.d . But that is a worry for later.

5.3. Do and Explore

Spacemacs places it's help commands under "SPC h", so give those a try. A hint for new users, "SPC h d", opens up a plethora of information. I'm am proceeding under the assumption you have watched the video in 1) and so one of the topics only lightly discussed was the concept of major and minor modes. A buffer can have one major mode, and multiple minor modes. Of course, Emacs being Emacs, it's possible to have two major modes with the package Polymode. "SPC h d b" will pull up a buffer describing the currently active modes. You can access the Spacemacs beginner tutorial with "SPC h SPC", and then typing in "Beginner's Tutorial". Now you can navigate the tutorial with the movement keys you have just learned. The tutorial is also accessible here (or in Emacs, "SPC h r").

5.4. Customize

Lastly here is a step by step example to install the "helpful" package. This is just a concrete example of package installation & configuration process. This particular package was chosen simply because it extends the "self-documenting" aspect of Emacs.

If you have found a useful Emacs package, the installation differs slightly than vanilla Emacs. The first thing to do is check the spacemacs develop layers list to see if a layer has included your desired package. Lets do that with the "helpful" package. Huh. So it is already included in a layer! That makes life easier for us, we can follow the README installation instructions. Remember you can access your dotspacemacs configuration file with "SPC f e d". Don't forget to hit "SPC f e R" to reload your configuration after adding the layer to your ~/.spacemacs file.

Now if your package is not already pre-configured in a layer, it is most likely either on MELPA or Github. If it is a local package, I'm afraid you'll have to consult the README.md found in ~/.emacs.d/private/local . In fact, that README contains all the information we need for all three use cases above. Quoted below:

  1. For a local package:
    • Load the file explicitly, using the full path to the file, by placing a

      \`(load "~/.emacs.d/private/local/package-name")\` within the body of the \`dotspacemacs/user-config\` function of your dotspacemacs file.

      • Alternatively create a directory with the name of the package in the

      \`.emacs.d/private/local\` directory, and add that directory to the load-path variable by adding \`(some-package :location local)\` to the list \`dotspacemacs-additional-packages\` within the \`dotspacemacs/layers\` function of your dotspacemacs file. After placing your package file into this package-directory the file can be loaded, without requiring the full path, by placing a \`(require 'package-name)\` within the body of the \`dotspacemacs/user-config\` function of your dotspacemacs file.

  2. If the package is on (M)ELPA simply add the package name to the list \`dotspacemacs-additional-packages\` in your dotspacemacs file
  3. For a package hosted on github the recipe for github packages can be used i.e. add

    \`\`\` (some-package :location (recipe :fetcher github :repo "some/repo")) \`\`\`

    to the list \`dotspacemacs-additional-packages\` in your dotspacemacs file.

There is no substitute for reading the documentation of the package. Or the source code itself. Luckily, the package we are about to customize makes the latter task slightly easier. Let us pretend we want to customize a variable in our dotspacemacs file. Before we do that, let's switch to the previously opened ~/.spacemacs (dotspacemacs) file buffer with "SPC b b".

One important point to keep in mind is that all key bindings are simply calling a command. From the code and package docs we can see that "helpful-variable" is a command. To run any interactive function in Emacs, we will use M-x ("alt-x" or the Spacemacs way: "SPC SPC") and type in "helpful-variable". Before we run it by hitting RET (enter), we notice – thanks to helm, an emacs completion package – that the keybinding already set for that command is "C-h v". Good to know. Press ESC to exit.

"SPC b d", ESC, q and C-g are the common default bindings to close a buffer or window.

In our dotspacemacs file let's press "SPC s s" and type in "dotspacemacs-themes". Make sure our cursor is placed on the variable "dotspacemacs-themes" and use the keybind we learned earlier: "C-h v". The variable at our cursor is filled in and a helpful buffer is drawn up. Give it a quick read. If you are curious you can compare it to "SPC h d v" with the cursor on the same point. Try swapping the "dotspacemacs-themes" variable. Save, "SPC f s" and reload "SPC f e R".

dotspacemacs-themes '(spacemacs-light spacemacs-dark)

6. Conclusion

So there you have it. The universality and power of vim's modal editing combined with the endless flexibility of the emacs lisp interpreter. Made "modern" and accessible thanks to the blood, sweat, tears and smarts of open-source contributors. Where to go from here?

  • Install the appropriate layer for your favourite language and get working.
  • Explore the jewels known as the"killer features" of emacs:
    1. org-mode
    2. magit
    3. LSP
    4. mu4e
    5. dired
    6. calc
    7. info
    8. tramp
  • Try the browser extension Tridactyl to browse the web with vim keybindings.
  • Familiarize your self with Emacs Lisp or perhaps even Common Lisp?
  • A no-nonsense "hit the ground running" intro - Stevey's Blog Rants: Emergency Elisp
  • GNU Intro to Elisp Manual - Top (Programming in Emacs Lisp)
  • A much more powerful version of Jupyter notebooks once you get familiar with Emacs. In particular, this is thanks to the org-babel package.
  • Fear of missing out on the freshest news in the Emacs sphere? Sacha Chua has got you covered.

    Once you get comfortable enough, you may even want to remove Spacemacs and roll your own custom configuration. There is no rush at all. My thoughts on future blog posts include a showcase of three org-mode packages which are particularly dear to my heart: org-brain, org-agenda, and org-babel. I hope this tutorial has helped you, and have a wonderful day.

7. Troubleshooting

7.1. Emacs GUI session is killed upon waking from sleep

7.2. Performance tips and tricks

In the Lisp programming language family, Emacs Lisp is a derivative of Maclisp circa 1980's. For a general purpose programming language other lisp dialects are better suited, such as ANSI Common Lisp. Emacs Lisp however remains perfectly adequate as a Domain Specific Language (DSL) for editing text.

Emacs configs are treated less like a software program (for which typical best practices apply) and more like a throwaway script hacked together by copy-paste. When it comes to subpar Emacs performance, the culprit and resolution is not so different from performance problems in other languages: check for errors in your own code or the libraries you use. Performance comes from data structures, and efficiency from algorithms. To optimize, then it would be wise to profile first.

Open the built-in Emacs Profiler with SPC h P s.

Messing with the Emacs garbage collector is not a good idea. But if you must, check out the gcmh melpa package.

To see what functions are running at set times, see the variables timer-list and timer-idle-list.

8. Legacy Windows 10 Installation

  1. Prerequisites

    Check that you meet the requirements for running WSL2. "Win + r", type in "winver" and hit enter. Compare your Windows version with the below

    • For x64 systems: Version 1903 or higher, with Build 18362 or higher.
    • For ARM64 systems: Version 2004 or higher, with Build 19041 or higher.

8.1. Install Microsoft Windows Subsystem for Linux (WSL) & Your Linux Distribution

First, install the Microsoft Windows Subsystem for Linux version 2. Unless explicitly mentioned as WSL1, WSL refers to WSL version 2. WSL2 is recommended over WSL1 Unless you plan on using Linux commandline on files stored in the Native Windows file system instead of the WSL filesystem. I will go into more detail later, but the WSL filesystem is accessible in Windows Explorer and shows up as a network drive. If you are unsure, go with WSL2. This process is already documented by Microsoft (includes troubleshooting guidelines). Repeated here for completion's sake:

Enable the windows feature called "Windows subsystem for Linux" by either checking the box in the GUI screen. You can get there by searching "Turn Windows features on or off" in the control panel search box. Do the same for the check box titled "virtual machine platform". you can enable these 2 features via the shell as well.

OR open the power shell as administrator and run:

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

now you have to download and run the Linux kernel update package from Microsoft. Again make sure you download the right one for your CPU architecture.

8.2. Install X Server

This is the software that allows Linux to display GUI elements. You have many options here:

  1. Xming
  2. Mobaxterm
  3. Vcxsrv

I have chosen Vcxsrv. Simple installation and configuration. Download and run the sourceforge installer and you can launch the program by the "Xlaunch" shortcut. No need to change any of the settings. Click next until the end and you should see a system tray icon. Feel free to add the "X Launch" shortcut to your Windows (Win + R) folder.

After installation, create a new desktop shortcut and use the following command. Add the following command in the properties → shortcut →target

"C:\Program Files\VcXsrv\vcxsrv.exe" :0 -ac -terminate -lesspointer -multiwindow -clipboard -wgl -dpi auto

The last step before launching is to configure your X Server correctly. In the WSL terminal, export the DISPLAY variable.

$ export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
$ export LIBGL_ALWAYS_INDIRECT=1

The reason for the above is because the internal IP address of the WSL (2) server changes on reboot. Don't worry, the team at WSL has ensured that connections to WSL from Windows (Ex. localhost:8000) require no extra configuration. The snippet above for is for WSL to Windows 10 GUI applications. You will probably want to put the two export commands into your .bashrc file, located in '~/home/$USER$/' folder. We can do this after completing the steps below.

8.3. Install Emacs

Spacemacs is a preset configuration of Emacs, so we must first make sure Emacs is installed properly. The default Emacs build that comes with Ubuntu 20.04 on WSL doesn't support XWindows (the X Server we just installed). To fix this we are going to add Kevin Kelley's builds of Emacs with XWindows supports, simply by adding Kevin's PPA to WSL. Enter the following in the WSL Terminal.

sudo apt update && sudo apt upgrade
sudo add-apt-repository ppa:kelleyk/emacs
sudo apt update
sudo apt install emacs27

Now we are ready to proceed to 3

8.4. Why is my GUI Spacemacs interrupted by Sleep?

# Allows us to open links in Spacemacs to our Windows 10 browser
fix_wsl2_interop() {
    for i in $(pstree -np -s $$ | grep -o -E '[0-9]+'); do
        if [[ -e "/run/WSL/${i}_interop" ]]; then
            export WSL_INTEROP=/run/WSL/${i}_interop
        fi
    done
}

#Call the function
export -f fix_wsl2_interop
fix_wsl2_interop

I have kept this for last because this adds quite a bit of complexity to the installation process. It's best to make sure the above is familiar before marching on. WSL2 networking is still very much a work in progress, and WSLg was in the works at the time of writing. Therefore X server sessions are not kept alive after the computer goes to sleep. This can be a deal breaker for some. If that is the case, then here is the workaround I use: courtesy of Mr. Christian Koberl.

DO NOT uninstall or change your previous VCXSRV setup. I keep both X2Go and VCXSRV open as otherwise my clipboard will stop working. Hard to debug.

After each WSL/Windows restart

  • Launch ssh in Linux (if not started yet): sudo service ssh start
  • Launch “X2Go Client” on Windows ad connect to the server with WSL user/password
  • Now you can launch X11 apps via the tray icon (see X2Go Published Applications)

To get sound you can use this link, How To Get Sound (PulseAudio) To Work On WSL2 - Linux Uprising Blog

The reason I do not use this option is due to battery usage as indicated by the Windows task manager. X2go client uses pulseaudio server and the cpu usage for windows audio process will be stuck around 8-10% CPU. My elfeed-mpv function is also very slow. I will have to wait until WSLg before managing my music with Emacs.

Under Options → Settings → Pulseaudio settings, you can now disable audio input (microphone support.) This itself is desirable for many users, but it also serves as a workaround for the issue of PulseAudio failing to do output simply because input is unavailable. – doc:release-notes-mswin:x2goclient-4.0.5.1 {X2Go - everywhere@home}

9. Sources and Credits

Footnotes:

1

Judges 21:24 DRA. What would medieval Thomists think of the word "self-actualization"? Can man remake himself in his own image anymore than a creature can be the first cause of itself, to reduce his potential to actual in such a manner?