Adding New Color Schemes to Windows Terminal
PowerShell, Windows Terminal ·Update 12/22/2019: There have been several changes to Windows Terminal since this was originally written so you can expect to encounter errors if you follow along with the provided code.
Windows Terminal
I’ve been having a lot of fun with the new Windows Terminal. One issue that I found is that I couldn’t find an appropriate color scheme to go with my background. I tried using the ColorTool, but that wasn’t working for me.
In this post we are going to look at the Windows Terminal settings file and see how we can interact with it. From there, we will write a script that will download all of the color schemes that we want and add them to our settings file for us.
Settings
The Windows Terminal settings are stored in a file called profiles.json
. You can open up this file in your default editor by pressing ctrl + ,
while in the Windows Terminal. You could also click the drop down arrow in the top-right and click on settings yourself, but I don’t recommend using your mouse.
JSON files are commonly used to store settings. PowerShell is well equipped to interact with them using ConvertFrom-Json
. Windows Terminal stores the profiles.json
file at C:\Users\$Env:Username\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\RoamingState\profiles.json
.
Acessing profiles.json from PowerShell
$profilePath = "C:\Users\$Env:Username\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\RoamingState\profiles.json"
$profile = Get-Content $ProfilePath | ConvertFrom-Json
$profile | Get-Member -MemberType NoteProperty
Updating profiles.json from PowerShell
$profile
now contains an object representing the profiles.json
file. As an example, we can change the theme of Windows Terminal by changing the requestedTheme
property inside of globals
.
# Display the global properties
$profile.globals
# Update the requestedTheme to dark mode
$profile.globals.requestedTheme = 'dark'
# update the profiles.json file with the updated object
$profile |
ConvertTo-Json |
Set-Content -Path $profilePath
The Windows Terminal default theme is now dark, which should be much better.
Color Schemes
In the profile.json
file there is a section dedicated to schemes. A color scheme determines the color of the text that is displayed in the Terminal.
View Your Color Schemes
By default there are only 6 schemes that come with Windows Terminal. You can select between, Ubuntu, UbuntuLegit, Campbell, Solarized Dark, Solarized Light.
# View your currently configured color schemes
$profile.schemes.name
Update your Color Scheme
Color schemes are applied to each of your profiles. We are going to update the color scheme for the profile that launches powershell.
# Display all profiles
$profile.profiles
$powershellExes = @('powershell.exe' , 'pwsh.exe')
# Grab first powershell profile and update the colorScheme
($profile.profiles |
Where-object commandline -in $powershellExes |
Select-Object -First 1).colorScheme = 'UbuntuLegit'
# Save the results
$profile |
ConvertTo-Json |
Set-Content -Path $profilePath
Get New Color Schemes
I’m not happy that it only ships with 5 schemes. Fortunately, there is a project on GitHub that has exactly what we want. If we look at the iTerm2-Color-Schemes Repository we can get a listing of color schemes that are meant to be added to the Windows Terminal.
We are able to add the contents of any of the JSON
files to the schemes section of our profile.json
file and then you can refer to the new theme in the colorScheme property of a profile.
That sounds like too much work for me. I’m pretty greedy and enjoy anything that is free so I’d like to script this so I can just use PowerShell to do the hard work for me. Who wants to spend their time updating JSON
files. Yuck!
Get-WtScheme
This function will return all of the themes from the repository. This will make it easy to update the profile.json
with all of the themes.
Function Get-WtScheme {
<#
.Description
Returns color schemes from
https://github.com/mbadolato/iTerm2-Color-Schemes/blob/master/windowsterminal
.Parameter Url
Url to the iTerm2 project.
.Parameter Theme
Specify the name of the theme that you want returned. All themes are returned by default
.Example
PS> Get-WtTheme
Returns all available themes
.Example
PS> Get-WtTheme -Filter 'atom.json'
Retrieves the atom.json theme.
.Link
https://github.com/mbadolato/iTerm2-Color-Schemes/blob/master/windowsterminal/
.Link link to blogpost
#>
[cmdletbinding()]
param(
[string]
$Theme = '*',
[string]
$Url = 'https://github.com/mbadolato/iTerm2-Color-Schemes/tree/master/windowsterminal'
)
$page = Invoke-WebRequest $Url -UseBasicParsing
$links = $page.Links | Where-Object title -like "$Theme.json"
Write-Verbose "$($links.count) links found matching $Theme"
foreach ($link in $links) {
# Use the raw url so raw results can be returned and output
$base = 'https://raw.githubusercontent.com'
$href = $link.href
$rawUrl = $base + $href
$rawUrl = $rawUrl.replace('/blob', '')
Invoke-RestMethod $RawUrl
}
}
Completed Gist
The gist is the final product. Just copy and paste into your terminal and run it. I opted to avoid writing this as a script or a module because I want it to be copy/pastable from the blog post. I hope that this saves you some time.