WSL 2 and terminals
Tags: wsl, terminals, tutorial
Published: 2021-04-16 08:41:13

My [previous post](https://dev.to/paddymorgan84/wsl-2-and-docker-329f) focussed on configuring Docker Desktop so that you could integrate seamlessly with WSL 2.

In this post, I wanted to talk about setting up a standalone terminal for WSL 2. Over the time I've used WSL I've worked with a couple myself and wanted to tell you about my experiences with them, as well as how I configured them for WSL 2.

---

## VS Code integrated terminal

I predominantly operate within VS Code as part of any work and personal projects I'm doing. The natural choice when it came to using a terminal was to use the one integrated into VS Code.

The experience with WSL is seamless. Once you've opened your project in WSL, you can open the terminal pane with `ctrl + '`

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0a7ftqzmv5otor0mdltd.png)

If you want to open additional terminals, you can do so with `ctrl + shift + '`

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h0z9vxdsu859azsrhiy9.png) 

I personally find the size of the terminal restrictive. I've tried to mitigate this to an extent by adding a few of my own key bindings to make the most out of the somewhat limited space:

- `ctrl + up` - Resize the terminal pane to make it larger
- `ctrl + down` - Resize the terminal pane to make it smaller
- `ctrl + s` - Split existing terminal
- `ctrl + x` - Toggle terminal pane being maximised
- `ctrl + shift + t` - Switch focus from terminal pane to editor (and vice versa)

You can set your own key bindings up by using `ctrl + k ctrl + s`, this will bring up the keybindings page. You'll notice that some of the bindings I use are fairly common and likely taken by other commands, `ctrl + s` for example. One nice feature with VS Code is that you can add conditional factors for when a keybinding will trigger. 

Using `ctrl + s` as an example, it's actually used on 3 occasions, but only triggers on certain conditions that I have specified, making each command unique:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dft7bk285intgxzgu0dq.png) 
 
You can find the rest of my VS Code key bindings in my [dotfiles](https://github.com/paddymorgan84/dotfiles/blob/master/vscode/keybindings.json) repo.

In general, I find the integrated terminal perfectly adequate for what I need. One thing I wish would change, however, is the fact that [you can't use VS Code across multiple monitors](https://github.com/Microsoft/vscode/issues/10121). I have a dual-screen setup, and after coming from the world of Visual Studio, it felt very natural for me to use one screen for my code, and the second screen for other purposes; such as debugging, terminals, problems and any other outputs I want to display.

As a result, I started looking into using a standalone terminal for times when the VS Code integrated terminal isn't quite enough.

---

## Hyper

One recommendation I received was [Hyper.js](https://hyper.is/). Hyper is an open-source terminal built using [Electron](https://www.electronjs.org/). This immediately appealed to me; I find myself crossing OS boundaries more and more often, so having a consistent terminal across them all would be ideal.

Much like VS Code, it offered a [wide range of extensions to enhance your experience](https://github.com/bnb/awesome-hyper). Adding plugins in itself is straightforward; with Hyper open, just press `ctrl + ,` and the `hyper.js` config will appear. You just need to add the plugin names and Hyper will load them for you:

```js
  plugins: [
     "hyper-dracula",
     "hyper-tabs-enhanced",
     "hyper-spotify",
     "hyper-blink", 
     "hyper-tab-icons"
     //"hyper-solarized-dark"
     //"hyper-material-theme"
],
```

You can set up integration with WSL with a couple of changes in your `hyper.js` file:

```js
    shell: 'C:\\Windows\\System32\\wsl.exe',
    shellArgs: ['~', '-d', 'Ubuntu-18.04'],
```

I'm specifying the `-d` flag in the `shellArgs` to determine the distro I want to open, which in this case is `Ubuntu-18.04`. I've also included `~` as an additional argument so that the shell opens in my WSL home directory. Without it, Hyper will default to your Windows `%userprofile%` directory. 

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oy4x9a4swzfq4eg6e4t8.png)
 
You can see my full configuration file in my [dotfiles](https://github.com/paddymorgan84/dotfiles/blob/master/hyper/.hyper.js) repo.

Although I was initially quite excited with what Hyper had to offer, it didn't take me long to become frustrated with it. It has a wide array of plugins, but I found that a lot of them just didn't work with Windows, leaving me with a rather limited terminal experience. It also [restricts you to configuring just one shell](https://github.com/vercel/hyper/issues/1147), something I wanted to avoid as I often switch between WSL and Powershell.

---

## Windows Terminal

[Windows Terminal](https://github.com/microsoft/terminal) is a relatively new terminal application developed by Microsoft. Not only does it support built-in tabs, but it also allows you to configure separate profiles where you can customise a variety of different shells:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0y2k8dmjy3omjvgq7sx9.png)

Better yet, I can split my terminal vertically (`Alt + Shift + +`) or horizontally (`Alt + Shift + -`) to view them both at once:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jy79722q1osogcpil0iv.png)
 
From an aesthetics point of view, Windows Terminal is heavily customisable as well. You can change the colour scheme, change background opacity, and if, like me, you're a fan of using programming ligature through fonts like [Fira Code](https://github.com/tonsky/FiraCode), there's support for that too. You can even configure background images for each profile:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cqg5sjim6fcphkz4zfzn.png)

Getting configured with WSL is pretty easy too. Here's the profile I have configured in the settings, which you can open with `ctrl + ,`:

```json
{
  "guid": "{c6eaf9f4-32a7-5fdc-b5cf-066e8a4b1e40}",
  "hidden": false,
  "name": "Ubuntu-18.04",
  "fontFace": "Fira Code",
  "source": "Windows.Terminal.Wsl",
  "startingDirectory": "\\\\wsl$\\Ubuntu-18.04\\home\\paddy",
  "colorScheme": "Dracula"
},
```

You can see my full configuration file in my [dotfiles](https://github.com/paddymorgan84/dotfiles/blob/master/windows-terminal/settings.json) repo.

If you want to go an extra step with Windows Terminal there's a very nice [extension](https://marketplace.visualstudio.com/items?itemName=Tyriar.windows-terminal) you can install for VS Code. The extension gives you the ability to open Windows Terminal from VS Codes context menu, but I've extended my [keybindings](https://github.com/paddymorgan84/dotfiles/blob/ace3a9572fb56d89d07f061c54cf93fcea7e0235/vscode/keybindings.json#L65) to speed the process up a little. This way I just need a couple of keystrokes and I have a maximised Windows Terminal available on my other monitor.

---

## That's a wrap

That's part 4 of my **WSL while you work** series finished, I hope you found it useful :+1:

Choosing and configuring your terminal is a very personal process, so this post acts as more of a guide to my experiences, as well as some help with integrating them with WSL 2. 

For me, using a combination of VS Codes offering in tandem with Windows Terminal is working really well, and I'm enjoying personalising both tools over time to make myself more productive in my day-to-day working life.

Next up, I'll be discussing configuring global level settings for WSL using `.wslconfig`.

---

## Credit

[Prateek Katyal](https://unsplash.com/@prateekkatyal) for the photo :camera: