Skip to content

Instantly share code, notes, and snippets.

@Jaykul
Last active July 10, 2021 06:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Jaykul/7d5c4829d3095632f11548c94cb37024 to your computer and use it in GitHub Desktop.
Save Jaykul/7d5c4829d3095632f11548c94cb37024 to your computer and use it in GitHub Desktop.
I wrote all of this just to get Split-WTTab

I've been using Windows Terminal since the source code was released, and now that we have support for split panes, I wanted a way to easily create a tab with three panes (one for each version of PowerShell I want to test against).

Unfortunately, there's no support for opening tabs from the command-line yet, nor is there any support yet for specifying which profile to use in a new split terminal. There are open issues for those features, but although I've done a PR or two for it, I didn't think it would be an easy thing to pull together, but I knew that new tabs use the default profile.

Switching the default profile and then creating a new split with the hotkeys works great, but I wanted to set the default profile more easily than editing it in a text editor -- even though one of my profile hacks is to set the profile GUIDs to numbers I can easily remember.

Anyway.

I hacked this script together in the evening last night after my kids went to bed. It is exactly one "free time" worth of effort, so please don't expect it to be bug-free. One sad thing about it is that I have formatted it such that I can fold on braces and still see the profile and color scheme names -- but the script module below ruins the formatting if you change anything.

Unfortunately I don't have any json libraries handy that can modify json and leave it in it's current format. PowerShell turns everything into custom objects and hashtables, and pretty-formats the json (in a way that's wastefully huge) when you write it out.

I've also included my WindowsTerminal profile, as a reference (since it's working with this script module).

{
"globals" :
{
"alwaysShowTabs" : true,
"defaultProfile" : "{00000000-0000-0000-0000-00000000007b}",
"initialCols" : 120,
"initialRows" : 30,
"requestedTheme": "system",
"showTabsInTitlebar": true,
"showTerminalTitleInTitlebar": true,
"wordDelimiters": " ./\\()\"'-:,.;<>~!@#$%^&*|+=[]{}~?\u2502",
"keybindings" : [
{ "command": "openNewTabDropdown", "keys": [ "ctrl+n"] },
{ "command": "closeTab", "keys": [ "ctrl+w" ] },
{ "command": "newTab", "keys": [ "ctrl+t" ] },
{ "command": "nextTab", "keys": [ "ctrl+tab" ] },
{ "command": "openSettings", "keys": [ "ctrl+," ] },
{ "command": "prevTab", "keys": [ "ctrl+shift+tab" ] },
{ "command": "scrollDown", "keys": [ "ctrl+shift+down" ] },
{ "command": "scrollDownPage", "keys": [ "ctrl+shift+pgdn" ] },
{ "command": "scrollUp", "keys": [ "ctrl+shift+up" ] },
{ "command": "scrollUpPage", "keys": [ "ctrl+shift+pgup" ] },
{ "command": "newTabProfile0", "keys": [ "ctrl+shift+p" ] },
{ "command": "newTabProfile1", "keys": [ "ctrl+shift+6" ] },
{ "command": "newTabProfile2", "keys": [ "ctrl+shift+w" ] },
{ "command": "newTabProfile3", "keys": [ "ctrl+shift+d" ] },
{ "command": "newTabProfile4", "keys": [ "ctrl+shift+b" ] },
{ "command": "newTabProfile5", "keys": [ "ctrl+shift+u" ] },
{ "command": "newTabProfile6", "keys": [ "ctrl+shift+z" ] },
{ "command": "switchToTab0", "keys": [ "ctrl+1" ] },
{ "command": "switchToTab1", "keys": [ "ctrl+2" ] },
{ "command": "switchToTab2", "keys": [ "ctrl+3" ] },
{ "command": "switchToTab3", "keys": [ "ctrl+4" ] },
{ "command": "switchToTab4", "keys": [ "ctrl+5" ] },
{ "command": "switchToTab5", "keys": [ "ctrl+6" ] },
{ "command": "switchToTab6", "keys": [ "ctrl+7" ] },
{ "command": "switchToTab7", "keys": [ "ctrl+8" ] },
{ "command": "switchToTab8", "keys": [ "ctrl+9" ] },
{ "command": "splitHorizontal", "keys": ["alt+-"] },
{ "command": "splitVertical", "keys": ["alt+plus"] },
{ "command": "resizePaneLeft", "keys": ["alt+shift+left"] },
{ "command": "resizePaneRight", "keys": ["alt+shift+right"] },
{ "command": "resizePaneUp", "keys": ["alt+shift+up"] },
{ "command": "resizePaneDown", "keys": ["alt+shift+down"] },
{ "command": "moveFocusLeft", "keys": ["alt+left"] },
{ "command": "moveFocusRight", "keys": ["alt+right"] },
{ "command": "moveFocusUp", "keys": ["alt+up"] },
{ "command": "moveFocusDown", "keys": ["alt+down"] },
{ "command": "closePane", "keys": ["alt+w"] }
]
},
"profiles" :
[
{ "name": "PowerShell 7 Preview",
"commandline": "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe",
"background": "#560124",
"colorScheme" : "Darkish",
"cursorColor" : "#FFFFFF",
"cursorShape" : "bar",
"fontFace" : "Fira Code",
"fontSize" : 10,
"guid" : "{00000000-0000-0000-0000-00000000007b}",
"padding" : "0, 0, 0, 0",
"icon": "ms-appdata:///roaming/Powershell_avatar.ico",
"backgroundImageAlignment": "bottomRight",
"backgroundImage": "ms-appdata:///roaming/Powershell_avatar256.png",
"backgroundImageStretchMode": "none",
"backgroundImageOpacity": 0.4,
"useAcrylic" : true
},
{ "name" : "PowerShell Core 6",
"commandline" : "C:\\Program Files\\PowerShell\\6\\pwsh.exe",
"fontFace" : "Fira Code",
"colorScheme": "Darkish",
"fontSize" : 10,
"guid" : "{00000000-0000-0000-0000-000000000006}",
"icon" : "ms-appdata:///roaming/Powershell_black.ico",
"padding" : "0, 0, 0, 0",
"startingDirectory" : "%USERPROFILE%",
"backgroundImageAlignment": "bottomRight",
"backgroundImage": "ms-appdata:///roaming/Powershell_black256.png",
"backgroundImageStretchMode": "none",
"backgroundImageOpacity": 0.4,
"useAcrylic" : true
},
{ "name" : "Windows PowerShell",
"commandline" : "powershell.exe",
"colorScheme": "Darkish",
"background" : "#012456",
"fontFace" : "Fira Code",
"fontSize" : 10,
"guid" : "{00000000-0000-0000-0000-000000000005}",
"icon" : "ms-appx:///ProfileIcons/{61c54bbd-c2c6-5271-96e7-009a87ff44bf}.png",
"backgroundImageAlignment": "bottomRight",
"backgroundImage": "ms-appdata:///roaming/PowerShell_blue256.png",
"backgroundImageStretchMode": "none",
"backgroundImageOpacity": 0.4,
"padding" : "0, 0, 0, 0",
"startingDirectory" : "%USERPROFILE%",
"useAcrylic" : true
},
{ "name" : "cmd",
"commandline" : "cmd.exe",
"acrylicOpacity" : 0.75,
"fontFace" : "Fira Code",
"fontSize" : 10,
"guid" : "{00000000-0000-0000-0000-00000000000d}",
"icon" : "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png",
"padding" : "0, 0, 0, 0",
"startingDirectory" : "%USERPROFILE%",
"useAcrylic" : true
},
{ "name" : "Ubuntu (bash)",
"commandline" : "ubuntu run bash",
"fontFace" : "Fira Code",
"fontSize" : 10,
"guid" : "{00000000-0000-0000-0000-00000000000b}",
"icon" : "ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png",
"backgroundImageAlignment": "bottomRight",
"backgroundImage": "ms-appdata:///roaming/Ubuntu_256.png",
"backgroundImageStretchMode": "none",
"backgroundImageOpacity": 0.4,
"padding" : "0, 0, 0, 0",
"useAcrylic" : true
},
{ "name" : "Ubuntu (pwsh)",
"commandline" : "ubuntu run pwsh",
"acrylicOpacity" : 0.80000001192092896,
"fontFace" : "Fira Code",
"fontSize" : 10,
"guid" : "{00000000-0000-0000-1000-000000000006}",
"icon" : "ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png",
"backgroundImageAlignment": "bottomRight",
"backgroundImage": "ms-appdata:///roaming/Ubuntu_256.png",
"backgroundImageStretchMode": "none",
"backgroundImageOpacity": 0.4,
"padding" : "0, 0, 0, 0",
"useAcrylic" : true
},
{ "name" : "CloudShell",
"commandline" : "%OneDrive%\\Documents\\WindowsPowerShell\\Tools\\azshell.exe",
"acrylicOpacity" : 0.85000002384185791,
"background" : "#012456",
"closeOnExit" : false,
"fontFace" : "Fira Code",
"fontSize" : 10,
"guid" : "{00000000-0000-1000-1000-000000000006}",
"icon" : "ms-appdata:///roaming/azure.png",
"padding" : "0, 0, 0, 0",
"useAcrylic" : true
}
],
"schemes" :
[
{ "name" : "Campbell",
"background" : "#0C0C0C",
"black" : "#0C0C0C",
"blue" : "#0037DA",
"brightBlack" : "#767676",
"brightBlue" : "#3B78FF",
"brightCyan" : "#61D6D6",
"brightGreen" : "#16C60C",
"brightPurple" : "#B4009E",
"brightRed" : "#E74856",
"brightWhite" : "#F2F2F2",
"brightYellow" : "#F9F1A5",
"cyan" : "#3A96DD",
"foreground" : "#F2F2F2",
"green" : "#13A10E",
"purple" : "#881798",
"red" : "#C50F1F",
"white" : "#CCCCCC",
"yellow" : "#C19C00"
},
{ "name": "Darkish",
"background" : "#212021",
"black" : "#212021",
"blue" : "#01A0E4",
"brightBlack" : "#493F3F",
"brightBlue" : "#6ECEFF",
"brightCyan" : "#95F2FF",
"brightGreen" : "#6CD18E",
"brightPurple" : "#D29BC6",
"brightRed" : "#FF6E6D",
"brightWhite" : "#FFFCFF",
"brightYellow" : "#FFFF85",
"cyan" : "#55C4CF",
"foreground" : "#FFFCFF",
"green" : "#01A252",
"purple" : "#A16A94",
"red" : "#D92D20",
"white" : "#A5A2A2",
"yellow" : "#FBED02"
},
{ "name": "Lightish",
"background" : "#FFFFFF",
"black" : "#000000",
"blue" : "#0073C3",
"brightBlack" : "#454545",
"brightBlue" : "#12A8CD",
"brightCyan" : "#2BC2A7",
"brightGreen" : "#81B600",
"brightPurple" : "#C05478",
"brightRed" : "#CA7073",
"brightWhite" : "#FFFFFF",
"brightYellow" : "#CC9800",
"cyan" : "#008E81",
"foreground" : "#000000",
"green" : "#4A8100",
"purple" : "#8F0057",
"red" : "#BE0000",
"white" : "#848388",
"yellow" : "#BB6200"
},
{ "name": "One Half Dark",
"background" : "#282C34",
"black" : "#282C34",
"blue" : "#61AFEF",
"brightBlack" : "#5A6374",
"brightBlue" : "#61AFEF",
"brightCyan" : "#56B6C2",
"brightGreen" : "#98C379",
"brightPurple" : "#C678DD",
"brightRed" : "#E06C75",
"brightWhite" : "#DCDFE4",
"brightYellow" : "#E5C07B",
"cyan" : "#56B6C2",
"foreground" : "#DCDFE4",
"green" : "#98C379",
"purple" : "#C678DD",
"red" : "#E06C75",
"white" : "#DCDFE4",
"yellow" : "#E5C07B"
},
{ "name": "One Half Light",
"background" : "#FAFAFA",
"black" : "#383A42",
"blue" : "#0184BC",
"brightBlack" : "#4F525D",
"brightBlue" : "#61AFEF",
"brightCyan" : "#56B5C1",
"brightGreen" : "#98C379",
"brightPurple" : "#C577DD",
"brightRed" : "#DF6C75",
"brightWhite" : "#FFFFFF",
"brightYellow" : "#E4C07A",
"cyan" : "#0997B3",
"foreground" : "#383A42",
"green" : "#50A14F",
"purple" : "#A626A4",
"red" : "#E45649",
"white" : "#FAFAFA",
"yellow" : "#C18301"
},
{ "name": "Solarized Dark",
"background" : "#073642",
"black" : "#073642",
"blue" : "#268BD2",
"brightBlack" : "#002B36",
"brightBlue" : "#839496",
"brightCyan" : "#93A1A1",
"brightGreen" : "#586E75",
"brightPurple" : "#6C71C4",
"brightRed" : "#CB4B16",
"brightWhite" : "#FDF6E3",
"brightYellow" : "#657B83",
"cyan" : "#2AA198",
"foreground" : "#FDF6E3",
"green" : "#859900",
"purple" : "#D33682",
"red" : "#D30102",
"white" : "#EEE8D5",
"yellow" : "#B58900"
},
{ "name": "Solarized Light",
"background" : "#FDF6E3",
"black" : "#073642",
"blue" : "#268BD2",
"brightBlack" : "#002B36",
"brightBlue" : "#839496",
"brightCyan" : "#93A1A1",
"brightGreen" : "#586E75",
"brightPurple" : "#6C71C4",
"brightRed" : "#CB4B16",
"brightWhite" : "#FDF6E3",
"brightYellow" : "#657B83",
"cyan" : "#2AA198",
"foreground" : "#073642",
"green" : "#859900",
"purple" : "#D33682",
"red" : "#D30102",
"white" : "#EEE8D5",
"yellow" : "#B58900"
},
{ "name": "Seoul256 Light",
"background" : "#FDF6E3",
"black" : "#4E4E4E",
"blue" : "#85ADD4",
"brightBlack" : "#E4E4E4",
"brightBlue" : "#ADD4FB",
"brightCyan" : "#87D7D7",
"brightGreen" : "#87AF87",
"brightPurple" : "#FFAFAF",
"brightRed" : "#D75F87",
"brightWhite" : "#D0D0D0",
"brightYellow" : "#FFD787",
"cyan" : "#87AFAF",
"foreground" : "#073642",
"green" : "#5F865F",
"purple" : "#D7AFAF",
"red" : "#D68787",
"white" : "#626262",
"yellow" : "#D8AF5F"
}
]
}
#requires -Module WASP
Update-TypeData -TypeName "WindowsTerminal.Profile" -DefaultDisplayProperty Name -DefaultDisplayPropertySet "Name", "Guid", "CommandLine" -Force
function Import-WTConfiguration {
[CmdletBinding()]
param()
begin {
if (!($package = $(Split-Path (Split-Path ((Get-Process -Name WindowsTerminal).Path -replace "_.*_", "_")) -Leaf))) {
$package = "Microsoft.WindowsTerminal_8wekyb3d8bbwe"
}
$ProfilePath = Convert-Path $Env:LOCALAPPDATA\Packages\$Package\*\profiles.json | Select-Object -First 1
}
end {
Get-Content $ProfilePath | ConvertFrom-Json | ForEach-Object {
$_.PSTypeNames.Insert(0, "WindowsTerminal.Config")
$_
}
}
}
function Export-WTConfiguration {
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[PSTypeName("WindowsTerminal.Config")]
$Config
)
begin {
if (!($package = $(Split-Path (Split-Path ((Get-Process -Name WindowsTerminal).Path -replace "_.*_", "_")) -Leaf))) {
$package = "Microsoft.WindowsTerminal_8wekyb3d8bbwe"
}
$ProfilePath = Convert-Path $Env:LOCALAPPDATA\Packages\$Package\*\profiles.json | Select-Object -First 1
}
process {
$config | ConvertTo-json -Depth 10 | Set-Content $ProfilePath
}
}
function Set-WTDefaultProfile {
<#
.SYNOPSIS
Sets the default profile by name
#>
[CmdletBinding()]
param(
# The name of the profile to set as default. Requires the profiles to have a name
[Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
[String]$Name
)
begin {
$config = Import-WTConfiguration
}
process {
if ($guid = $config.profiles.Where{ $_.Name -eq $Name }.guid) {
$config.globals.defaultProfile = $guid
} else {
Write-Error "$Name profile not found"
}
}
end {
$config | Export-WTConfiguration
}
}
function Get-WTProfile {
<#
.SYNOPSIS
Gets one or more Windows Terminal profiles by name
#>
[CmdletBinding()]
param(
# The name of the profile, supports wildcards
[Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
[String[]]$Name = "*"
)
begin {
$config = Import-WTConfiguration
}
process {
$index = 0
$profiles = $config.profiles.ForEach{
$_.PSTypeNames.Insert(0, "WindowsTerminal.Profile")
$_ | Add-Member NoteProperty "index" ($index++)
$_
}
# loop the name so they come out in name order instead of index order
foreach ($n in $Name) {
$profiles.Where{
$_.Name -like $N
}.ForEach{
Write-Verbose "Get-WTProfile $N --> $($_.Name)"
$_
}
}
}
}
function Split-WTTab {
<#
.SYNOPSIS
Creates a tab with vertical splits, with the specified profile names
.EXAMPLE
Split-WTTab "PowerShell Core", "Windows PowerShell"
Creates a new tab split in half, with PS Core and Windows PowerShell
NOTE: this depends on the profile names, you may want to use Get-WTProfile to verify the names
.LINK
Get-WTProfile
#>
[CmdletBinding()]
param(
# The name of the profiles, supports wildcards
[String[]]$Name,
[Switch]$UseExistingTab
)
$config = Import-WTConfiguration
foreach ($WTProfile in Get-WTProfile $Name) {
Write-Verbose "Opening $($WTProfile.Name) ($($WTProfile.index)): $(if($UseExistingTab) { 'use existing tab' } else { 'in a split' })"
Set-WTDefaultProfile $WTProfile.Name
Start-Sleep -Milliseconds 200
if (!$UseExistingTab) {
PressKeyBinding $config.globals.keybindings.Where{ $_.command -match "newTabProfile$($WTProfile.index)" }.keys -ErrorAction Stop
} else {
PressKeyBinding $config.globals.keybindings.Where{ $_.command -match "splitVertical" }.keys -ErrorAction Stop
}
$UseExistingTab = $true
}
}
function PressKeyBinding {
# Requires the WASP module for the Input commands
[CmdletBinding()]
param(
$KeyBindingKeys
)
# Terminal only supports "Ctrl", "Alt", "Shift" but Add-Input uses "Control", "Menu", "Shift"
$Modifiers, $Keys = (
$KeyBindingKeys -replace "ctrl", "control" -replace "alt", "MENU" -split "\+" -replace "^plus$","+"
).Where( { $_ -match "Control|Shift|Menu" }, "Split")
Write-Verbose "Press key '$($Keys[0])' with modifiers: $($Modifiers)"
Add-Input $Keys[0] -Modifiers $Modifiers | Send-Input
}
@ninmonkey
Copy link

They finally added commands to open tabs in the current (or specific windows) 🥂

quote from: https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-7-release/

// Open a new tab with the default profile in the current window
wt -w 0 new-tab

// Open a new tab with the default profile in the third-created terminal window
wt -w 3 new-tab

// Open a new tab with the default profile in a new window
wt -w -1 new-tab

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment