Mike Slinn

Windows Terminal

— Draft —

Published 2019-05-02. Last modified 2024-08-24.
Time to read: 3 minutes.

Mac and native Linux users can skip this lecture.

This lecture shows you some important features of Microsoft Windows Terminal, and some easy ways to work with JSON, which is the format for Windows Terminal configuration data.

Windows Terminal requires Windows 10 version 18362.0. Run winver from a cmd prompt to discover your Windows 10 version. You should see the following dialog, which displays the OS build:

If you don't have the necessary version of Windows 10, navigate to Settings > Update & Security > Windows Update) and select Check for updates. Once the update appears, you can select Download and install now. This new ‘Download and install now’ menu option is available for Windows 10, version 1803 or version 1809 that also have the May 21st updates (or later) installed. For more information on the new user update controls and how to get the May 2019 Update, watch this video.

Once you have the required version of Windows you can install the Windows Terminal Preview app via the Microsoft Store.

Windows Terminal supports:

  • Custom Key Bindings
  • Custom themes/styles
  • Configurable background (acrylic blur or custom image)
  • Multiple tabs
  • Unicode and UTF-8 character support
  • GPU accelerated text rendering engine
  • PowerShell, CMD, WSL, WSL2

The GitHub project for Windows Terminal is pretty active.

Launch Windows Terminal

You have several ways to run Windows Terminal. Each of the following will open a new pane if Windows Terminal is already running:

  1. Type Windows-R wt Enter
  2. Type wt into a cmd shell or PowerShell and press Enter.
  3. If you are running Windows 10 (not 11), you can pin the Windows Terminal icon to the Start Menu or taskbar; you can click on its icon to launch it.
  4. Launch an instance of Windows Terminal from a bash prompt:
    Shell
    $ cmd.exe /c start wt.exe
    The program actually resides in the canonical directory %LOCALAPPDATA%\Microsoft\WindowsApps\wt.exe, which on my laptop expands to C:\Users\mslinn\AppData\Local\Microsoft\WindowsApps\wt.exe. A Windows alias is used to run wt.exe without requiring the actual directory that it resides in, otherwise I would have had to type this:
    Shell
    $ cmd.exe /c start /mnt/c/Users/mslinn/AppData/Local/Microsoft/WindowsApps/wt.exe

Windows Terminal settings.json Configuration File

The Windows Terminal configuration file is in JSON format. The native Windows canonical path to this file is: %AppData%\Local\Packages\Microsoft.Windows­Terminal_8wekyb3d8bbwe\Roaming­State\settings.json

%AppData% expands on my computer to C:\Users\mslinn\AppData. You can type %AppData% into the File Explorer address bar to see your Windows account's value for this environment variable. My expanded path to the Windows Terminal configuration file is: C:\Users\mslinn\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\RoamingState\settings.json

Here are my settings.json:

settings.json
{
   "$help":"https://aka.ms/terminal-documentation",
   "$schema":"https://aka.ms/terminal-profiles-schema-preview",
   "actions":[
      {
         "command":{
            "action":"copy",
            "singleLine":false
         },
         "id":"User.copy.644BA8F2",
         "keys":"ctrl+c"
      },
      {
         "command":"paste",
         "id":"User.paste",
         "keys":"ctrl+v"
      },
      {
         "command":"find",
         "id":"User.find",
         "keys":"ctrl+shift+f"
      },
      {
         "command":{
            "action":"splitPane",
            "split":"auto",
            "splitMode":"duplicate"
         },
         "id":"User.splitPane.A6751878",
         "keys":"alt+shift+d"
      }
   ],
   "alwaysShowNotificationIcon":true,
   "centerOnLaunch":false,
   "confirmCloseAllTabs":false,
   "copyFormatting":"none",
   "copyOnSelect":true,
   "defaultProfile":"{2c4de342-38b7-51cf-b940-2309a097f518}",
   "firstWindowPreference":"defaultProfile",
   "initialPosition":"5765,750",
   "minimizeToNotificationArea":false,
   "newTabMenu":[
      {
         "type":"remainingProfiles"
      }
   ],
   "profiles":{
      "defaults":{
         "font":{
            "face":"Consolas"
         }
      },
      "list":[
         {
            "commandline":"%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
            "guid":"{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
            "hidden":false,
            "name":"Windows PowerShell"
         },
         {
            "commandline":"%SystemRoot%\\System32\\cmd.exe",
            "guid":"{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
            "hidden":false,
            "name":"Command Prompt"
         },
         {
            "guid":"{b453ae62-4e3d-5e58-b989-0a998ec441b8}",
            "hidden":false,
            "name":"Azure Cloud Shell",
            "source":"Windows.Terminal.Azure"
         },
         {
            "bellStyle":"taskbar",
            "guid":"{2c4de342-38b7-51cf-b940-2309a097f518}",
            "hidden":false,
            "historySize":999999999,
            "name":"Ubuntu",
            "source":"Windows.Terminal.Wsl",
            "startingDirectory":"/home/mslinn",
            "tabTitle":null
         },
         {
            "guid":"{acbafd15-cbbb-5bb3-8a61-bed446ff4b83}",
            "hidden":false,
            "name":"Ubuntu 24.04 LTS",
            "source":"CanonicalGroupLimited.Ubuntu24.04LTS_79rhkp1fndgsc"
         }
      ]
   },
   "schemes":[

   ],
   "themes":[

   ],
   "trimBlockSelection":true,
   "useAcrylicInTabRow":true,
   "windowingBehavior":"useAnyExisting"
}

The contents of settings.json is documented here.

wslpath

WSL provides the /bin/wslpath script that converts a path between DOS/Windows and Unix/Linux format.

Shell
$ wslpath -h
Usage:
    -a    force result to absolute path format
    -u    translate from a Windows path to a WSL path (default)
    -w    translate from a WSL path to a Windows path
    -m    translate from a WSL path to a Windows path, with '/' instead of '\'
EX: wslpath 'c:\users'

We can use wslpath to convert the DOS/Windows path to the JSON configuration file for Windows Terminal into Unix/Linux format. I broke the path into three pieces because it was so long:

Shell
$ APPDATA='C:\Users\mslinn\AppData'
$ WINTERM_DIR="$APPDATA"'\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\RoamingState'
$ wslpath -u "$WINTERM_DIR"'\settings.json'
/mnt/c/Users/mslinn/AppData/Local/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/RoamingState/settings.json 

Windows Terminal Preview (which I use) has a similar directory structure, at Microsoft.Windows­TerminalPreview_8wekyb3d8bbwe instead of Microsoft.Windows­Terminal_8wekyb3d8bbwe:

Shell
$ APPDATA='C:\Users\mslinn\AppData'
$ WINTERM_DIR="$APPDATA"'\Local\Packages\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\LocalState'
$ wslpath -u "$WINTERM_DIR"'\settings.json'
/mnt/c/Users/mslinn/AppData/Local/Packages/Microsoft.TerminalPreview_8wekyb3d8bbwe/RoamingState/settings.json 

You can copy the WSL path to the system clipboard, shared between native Windows and WSL, by piping the output of wslpath to the Windows clip.exe command:

Shell
$ wslpath -u "$WINTERM_DIR"'\RoamingState\settings.json' | clip.exe

Below is one way to define an environment variable in bash called WTJ, which contains the path to the Windows Terminal or Terminal Preview settings file that we created a moment ago with wslpath:

Shell
$ WTJ="$( wslpath -u "$WINTERM_DIR"'\settings.json' )"

Check to ensure that WTJ has a valid value:

Shell
scala> ls "$WTJ"
/mnt/c/Users/mslinn/AppData/Local/Packages/Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe/LocalState/settings.json* 

Custom Key Bindings

You can define custom key bindings for Terminal functions; they are stored in the keybindings object within profiles.json. Some of the default keybindings are visible in the image to the right.

Background Images

Acrylic backgrounds and the blur effect are supported. Each profile can have a distinct background image. The default profiles have no background, but they can be added by defining values for backgroundImage, backgroundImageOpacity (which is set to 1.0 by default) and backgroundImageStretchMode, which has values stretch, uniformToFill.

Fonts

Three monospaced programming fonts you might be interested in are Fira Code, Monoid, and Hasklig. I tend to use Consolas whenever available.


* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.