Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/hubisan/emacs-wsl

Install and run Emacs with the Windows Subsystem for Linux (WSL 2) in Windows 10 or 11.
https://github.com/hubisan/emacs-wsl

emacs wsl

Last synced: about 2 months ago
JSON representation

Install and run Emacs with the Windows Subsystem for Linux (WSL 2) in Windows 10 or 11.

Awesome Lists containing this project

README

        

* Emacs-WSL :noexport:

This guide shows you how to run Emacs with the Windows Subsystem for Linux WSL2
using Ubuntu as Linux distribution.

#+caption: Graphical Emacs in Windows 10 with WSL2
[[./img/emacs-wsl.png]]

#+BEGIN_QUOTE
I've removed the detailed instructions on WSL 1 installation. For WSL 2, a link to the documentation is sufficient, as it's straightforward to install. If you're still using WSL 1, please refer to the older [[https://github.com/hubisan/emacs-wsl/tree/v1.2.0][version]] of this documentation.
#+END_QUOTE

* Contents :TOC_1_gh:
- [[#install-ubuntu][Install Ubuntu]]
- [[#install-emacs-29][Install Emacs 29]]
- [[#run-emacs-in-a-graphical-display][Run Emacs in a Graphical Display]]
- [[#run-emacs-in-terminal][Run Emacs in Terminal]]
- [[#optional-additions][Optional Additions]]
- [[#faq][FAQ]]

* Install Ubuntu

Go to [[https://learn.microsoft.com/en-us/windows/wsl/install][Install WSL | Microsoft Learn]] and follow the instructions to install WSL 2 with Ubuntu.

* Install Emacs 29

To install the latest Emacs 29 version in Ubuntu 22.04 follow those steps:

1. Install all dependencies (mostly taken from the [[https://github.com/alexmurray/emacs-snap/blob/master/snapcraft.yaml][snap]])\\

#+BEGIN_SRC shell
sudo apt update
sudo apt install -y autoconf automake bsd-mailx build-essential \
dbus-x11 debhelper dpkg-dev emacs-bin-common emacs-common g++-10 gawk \
gcc-10 git gvfs ibus-gtk3 language-pack-en-base libacl1-dev libasound2 \
libasound2-dev libaspell15 libasyncns0 libatk1.0-0 libatk-bridge2.0-0 \
libatspi2.0-0 libbrotli1 libc6 libc6 libc6-dev libc6-dev libcairo2 \
libcairo2-dev libcairo-gobject2 libcanberra0 libcanberra-gtk3-0 \
libcanberra-gtk3-module libdatrie1 libdb5.3 libdbus-1-3 libdbus-1-dev \
libdrm2 libegl1 libenchant-2-dev libepoxy0 libflac8 libfontconfig1 \
libfontconfig1-dev libfreetype6 libfreetype6-dev libgbm1 libgccjit0 \
libgccjit-10-dev libgcc-s1 libgdk-pixbuf2.0-0 libgif7 libgif-dev \
libgl1 libglib2.0-0 libglvnd0 libglx0 libgmp10 libgnutls28-dev \
libgnutls30 libgpm2 libgpm2 libgpm-dev libgraphite2-3 \
libgstreamer1.0-0 libgstreamer-gl1.0-0 libgstreamer-plugins-base1.0-0 \
libgtk-3-0 libgtk-3-dev libgudev-1.0-0 libharfbuzz0b libharfbuzz0b \
libharfbuzz-icu0 libhyphen0 libibus-1.0-5 libice6 libicu70 libisl23 \
libjansson4 libjansson-dev libjbig0 libjpeg8-dev libjpeg-dev \
libjpeg-turbo8 liblcms2-2 liblcms2-dev liblockfile1 liblockfile-dev \
libltdl7 libm17n-0 libm17n-dev libmpc3 libmpfr6 libncurses5-dev \
libnotify4 libnss-mdns libnss-myhostname libnss-sss libnss-systemd \
libogg0 liborc-0.4-0 liboss4-salsa2 libotf1 libotf-dev libpango-1.0-0 \
libpangocairo-1.0-0 libpangoft2-1.0-0 libpixman-1-0 libpng16-16 \
libpng-dev libpulse0 librsvg2-2 librsvg2-dev libsasl2-2 libsecret-1-0 \
libselinux1-dev libsm6 libsndfile1 libsoup2.4-1 libsqlite3-0 \
libsqlite3-dev libssl3 libsss-nss-idmap0 libstdc++6 libsystemd-dev \
libtdb1 libthai0 libtiff5 libtiff-dev libtinfo-dev libtree-sitter0 \
libtree-sitter-dev libvorbis0a libvorbisenc2 libvorbisfile3 \
libwayland-client0 libwayland-cursor0 libwayland-egl1 \
libwayland-server0 libwebkit2gtk-4.0-dev libwebp7 libwebpdemux2 \
libwebp-dev libwoff1 libx11-6 libx11-xcb1 libxau6 libxcb1 \
libxcb-render0 libxcb-shm0 libxcomposite1 libxcursor1 libxdamage1 \
libxdmcp6 libxext6 libxfixes3 libxfixes-dev libxi6 libxi-dev \
libxinerama1 libxkbcommon0 libxml2 libxml2-dev libxpm4 libxpm-dev \
libxrandr2 libxrender1 libxrender-dev libxslt1.1 libxt-dev libyajl2 \
mailutils procps quilt sharutils texinfo zlib1g-dev
#+END_SRC

There might be a dialog about the mail server configuration, just select ~no configuration~.

2. Clone the latest Emacs 29 version into =~/emacs=\\

Change the directory if you want to clone it somewhere else.

#+BEGIN_SRC shell
cd ~
git clone --depth 1 --branch emacs-29 git://git.sv.gnu.org/emacs.git
#+END_SRC

3. Configure and install Emacs\\

This step will take some time, and you might be prompted to enter your password once.

Optional features in used (feel free to remove any that you don't need):

- ~--with-native-compilation~ Compile with Emacs Lisp native compiler support.
- ~--with-json~ Compile with native JSON support. Is probably the default, when libjansson is installed.
- ~--with-tree-sitter~ Compile with tree-sitter. Is probably the default, when tree-sitter is installed.
- ~--with-xwidgets~ Enable use of xwidgets in Emacs buffers (requires gtk3 or macOS Cocoa).

Other compilation options you might want to enable:

- ~--with-pgtk~ Use GTK to support window systems other than X. If you want to use Wayland instead of X11.

#+BEGIN_SRC shell
cd ~/emacs
export CC="gcc-10" CXX="gcc-10"
./autogen.sh
./configure --with-native-compilation --with-json --with-tree-sitter --with-xwidgets
make -j$(nproc)
sudo make -j$(nproc) install
#+END_SRC

Retain the directory where Emacs was cloned for reinstallation (if a step fails), reconfiguration or uninstallation.

To check if Emacs is working, simply run it directly in the terminal using ~emacs -nw -q~.

** Update to a new Emacs version

To update to a new Emacs version, uninstall the current one by navigating to the installation folder (=~/emacs=) and executing ~sudo make uninstall~. Then pull and install the new version.

** Use latest Snapshot

To use the latest snapshot you can clone the master branch:

#+BEGIN_SRC shell
git clone --depth 1 git://git.sv.gnu.org/emacs.git
#+END_SRC

* Run Emacs in a Graphical Display

WSL 2 now supports ([[https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps][Run Linux GUI apps with WSL | Microsoft Learn]]) running Linux GUI applications (X11 and Wayland).

To run Emacs in graphical display just open the Ubuntu terminal and run ~emacs~. To make it detach the process from the controlling terminal use ~setsid emacs~.

* Run Emacs in Terminal

Run Emacs with ~emacs -nw~ in Ubuntu terminal.

* Optional Additions

** Use Windows Terminal

Install [[https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701?rtc=1&activetab=pivot:overviewtab][Windows Terminal]] from Microsoft from the Microsoft Store.

#+BEGIN_QUOTE
The Windows Terminal is a modern, fast, efficient, powerful, and productive terminal application for users of command-line tools and shells like Command Prompt, PowerShell, and WSL.
#+END_QUOTE

** Change keyboard layout

#+BEGIN_QUOTE
This only works if you use X11. If using wayland just switch the window keyboard layout for the Emacs application window like you do for any other application in Windows.
#+END_QUOTE

If you want to change the keyboard layout used make sure ~x11-xkb-utils~ is installed (~sudo apt install x11-xkb-utils~) and add, for instance

#+BEGIN_SRC shell
setxkbmap -layout us
#+END_SRC

to =~/.bashrc= or to an alias.

** Generate SSH Key

Generate a new ED25519 SSH key pair:

#+BEGIN_SRC shell
ssh-keygen -t ed25519 -C "[email protected]"
#+END_SRC

A dialog will ask you to:

- input a file path: use the suggested path by pressing ~Enter~
- enter a password: enter your password

To copy the generated ssh key into the clipboard use:

#+BEGIN_SRC shell
clip.exe < ~/.ssh/id_ed25519.pub
#+END_SRC

** SSH-agent with ssh-ident

~ssh-ident~ can be used as a simple way to utilize the SSH-agent.

~ssh-ident~ starts the SSH agent for a specific identity on demand (once you actually need them) and sets a customizable lifetime for that identity. Another approach would be to launch the SSH agent during WSL startup. However, this prompts for a password every time, even if it's not needed.

Install ~ssh-ident~ following the instructions provided in the [[https://github.com/ccontavalli/ssh-ident][documentation]].

The following configuration is necessary to enable ssh-ident to work seamlessly with Magit:

#+BEGIN_SRC emacs-lisp
;; Integrate with ssh-ident to ask for ssh password:
(add-to-list 'magit-process-password-prompt-regexps
"^\\(Enter \\)?[Pp]assphrase for [^ ]*: ?$")
(add-to-list 'magit-process-password-prompt-regexps
"^Bad passphrase, try again for [^ ]*: ?$")
#+END_SRC

** Use en_US Language

Bash on Ubuntu on Windows starts on the language defined in your Country or Region settings (maybe this got changed, not sure). If you want to change the default language to en_US you may need to run the following commands:

#+BEGIN_SRC shell
sudo apt install -y language-pack-en language-pack-en-base manpages
sudo locale-gen en_US.UTF-8
sudo update-locale LANG=en_US.UTF8
#+END_SRC

** Zsh and oh-my-zsh

If you want to use [[https://en.wikipedia.org/wiki/Z_shell][zsh]] and [[https://ohmyz.sh/][oh-my-zsh]]:

#+BEGIN_SRC shell
sudo apt install zsh
chsh -s $(which zsh)
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
#+END_SRC

Restart WSL.

In some scripts you need to change bash to zsh to be able to use it when emulating a terminal in Emacs.

** Shrink Title Bar If Using Wayland

Just use this [[file:wayland-css/gtk.css][css]] and save it as =~/.config/gtk-3.0/gtk.css=.

** Preserve X11 Connections to Hyper-V

#+BEGIN_QUOTE
[2023-12-14 Thu] Not sure if this is still relevant.
#+END_QUOTE

The network connection between Windows and WSL2 breaks when your machine goes into standby or hibernate. Graphical Emacs & other GUI apps will terminate.

Should you want to preserve your GUI Emacs sessions between sleep, there are three options:

1. Use X2Go - virtual X11 server with Windows client

This is the most preferred option

a) Fix SSH host keys

#+begin_src bash
sudo apt-get remove --purge openssh-server
sudo apt-get install openssh-server
sudo service ssh --full-restart
#+end_src

b) Install X2Go on your Linux distribution

#+begin_src bash
apt install x2goserver
#+end_src

c) [[code.x2go.org/releases/X2GoClient_latest_mswin32-setup.exe][Download]] and install the client for Windows.

d) Configure the

Host: localhost
Login:
Session type: Published Applications

e) 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 user/password Now you can launch X11 apps via the tray icon (see X2Go Published Applications)

Source: [[https://derkoe.dev/blog/development-environment-in-wsl2/][Development Environment in WSL2]]

2. Forward X11 unix socket from WSL2 via WSL1 to X410/Vcxsrv/etc. running on Windows

[[http://emacsredux.com/blog/2020/09/23/using-emacs-on-windows-with-wsl2/?ht-comment-id=688089][Using Emacs on Windows with WSL2 | Emacs Redux]]
[[https://github.com/microsoft/WSL/issues/4619#issuecomment-678652118][microsoft/WSL#4619 {WSL 2} WSL 2 cannot access windows service via localhost:...]]

3. WSL Daemon - Stable X11 connection for WSL2

[[https://github.com/nbdd0121/wsld][GitHub - nbdd0121/wsld: WSL Daemon - Stable X11 connection and time synchroni...]]

* FAQ

** Where is the root folder located?

The root is accessible as ~\\wsl$~ in file explorer.

** How to access Linux files from Windows?

Run ~explorer.exe .~ in WSL to open the Windows File Explorer at the current location. The path will start with ~\\wsl$~ unless it is a mounted drive. In the File Explorer the files and folders can be copied, moved and edited as usual (see this blog [[https://devblogs.microsoft.com/commandline/whats-new-for-wsl-in-windows-10-version-1903/][post]]).

** How start WSL from File Explorer in the current folder?

To start WSL from Windows File Explorer just type ~wsl~ into the location input box or hold down ~Shift~ while right-clicking and select ~Open Linux shell here~ from the context menu. If it's a network drive it has to be mounted else this will not work.