Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Subscribe
Archives
October 14, 2025

Finger Fun: More Keybinding Tips and Tricks

In this issue:

  • PSReadLine
    • Getting KeyBindings
    • Adding KeyBindings
  • Windows Terminal
    • Getting Windows Terminal KeyBindings
    • Getting Windows Terminal Actions
    • Get-WTAction
    • Get-WTKeyBinding
    • Adding Windows Terminal KeyBindings
  • Testing KeyBindings
    • Test-ChordBinding
  • Summary

I started my career back in the days of DOS so I am very comfortable working from a keyboard. In the early days of Windows I was a WordPerfect macro master. I would spend hours constructing a WordPerfect macro to automate document creation and management. A macro is just another type of keyboard shortcut.

Since I spend my days working from a PowerShell prompt, i am always looking for ways to speed up my work. I hate reaching for a mouse. I love it when I can type a few keys and have something happen. That's why I love keybindings in the PSReadLine module and Windows Terminal.

I've written about PSReadLine keybindings in the past.

  • PSReadLine Profile Power • Buttondown

    The PSReadLine module is one of the most useful tools we have in PowerShell. You utilize it every day without realizing it. An early version of the module...

  • More PSReadLine Power • Buttondown

    Last time, I showed you how to customize PSReadLine in your module by taking advantage of examples in the sample PSReadLine profile script. But since this...

But it has been a while since I wrote about keybindings. So, I thought it was time to revisit the topic.

> VSCode and the PowerShell ISE also have keybindings, but I'm not going to cover them here. Although you still need to be aware of potential conflicts.

PSReadLine

The PSReadLine module defines many default keybindings that we use all the time such as Ctrl+r and Ctrl+Space. The keybinding is defined as a chord. A chord is a combination of one or more modifier keys (Ctrl, Alt, Shift) and a System.ConsoleKey value.

System.ConsoleKey values
figure 1

Getting KeyBindings

You can run Get-PSReadLineKeyHandler -Bound to see all of the defined PSReadline keybindings. These are grouped by a Microsoft.PowerShell.KeyHandlerGroup value. You can see the available groups by running:

PS C:\> Get-TypeMember Microsoft.PowerShell.KeyHandlerGroup

   Type: Microsoft.PowerShell.KeyHandlerGroup

Name           MemberType ResultType                           IsStatic IsEnum
----           ---------- ----------                           -------- ------
Basic          Field      Microsoft.PowerShell.KeyHandlerGroup     True
Completion     Field      Microsoft.PowerShell.KeyHandlerGroup     True
CursorMovement Field      Microsoft.PowerShell.KeyHandlerGroup     True
Custom         Field      Microsoft.PowerShell.KeyHandlerGroup     True
History        Field      Microsoft.PowerShell.KeyHandlerGroup     True
Miscellaneous  Field      Microsoft.PowerShell.KeyHandlerGroup     True
Prediction     Field      Microsoft.PowerShell.KeyHandlerGroup     True
Search         Field      Microsoft.PowerShell.KeyHandlerGroup     True
Selection      Field      Microsoft.PowerShell.KeyHandlerGroup     True
GetType        Method     Type
HasFlag        Method     Boolean
ToString       Method     String

> Get-TypeMember is from the PSScriptTools module.

If I only want to see my custom keybindings, I can run:

PS C:\> Get-PSReadLineKeyHandler -Bound | Where group -eq custom

User defined functions
======================

Key        Function               Description
---        --------               -----------
Alt+%      ExpandAliases          Replace all aliases with the full command
F6         Function Menu          Display all functions as menu using Out-GridView. [jeff]
F7         HistoryList            Show command history with Out-GridView. [jeff]
(          InsertPairedBraces     Insert matching braces
{          InsertPairedBraces     Insert matching braces
[          InsertPairedBraces     Insert matching braces
Ctrl+j     JumpDirectory          Goto the marked directory.[jeff]
Alt+F5     ListMyHandlers         List my PSReadLineHandlers [jeff]
Ctrl+Alt+j MarkDirectory          Mark the current directory. [jeff]
Alt+k      my handlers            Show my custom PSReadline key handlers
Shift+F1   OnlineCommandHelp      Open online help for the current command. [jeff]
Ctrl+h     Open PSReadLineHistory View PSReadLine history file with the associated application. [...
Alt+(      ParenthesizeSelection  Put parenthesis around the selection or entire line and move th...
Alt+w      SaveInHistory          Save current line in history but do not execute. [jeff]
Alt+j      ShowDirectoryMarks     Show the currently marked directories. [jeff
"          SmartInsertQuote       Insert paired quotes if not already on a quote
'          SmartInsertQuote       Insert paired quotes if not already on a quote

Adding KeyBindings

I even defined a custom key binding to display my custom keybindings using Format-SpectreTable from the pwshSpectreConsole module

Set-PSReadLineKeyHandler -Chord "Alt+k" -BriefDescription "my handlers" -Description "Show my custom PSReadline key handlers" -ScriptBlock {
    Get-PSReadLineKeyHandler -bound |
    Where group -eq 'Custom' |
    Sort Key |
    Format-SpectreTable -Title "[italic gold1]My PSReadLine Key Handlers[/]" -Color 'SpringGreen3_1' |
    Out-Host
}
My custom PSReadline key handlers
figure 2

Many of my keybindings are defined in my PowerShell profile. I recommend defining them in a PowerShell script file that you can dot source from your profile. I wish there was a way to export and import the keybindings. Unfortunately, once you register the keybinding, you can't see the associated script block or PSReadLine function which means there's nothing to export. A PowerShell script file is your best option.

Windows Terminal

Where this gets interesting, or potentially more complicated, is when you add Windows Terminal into the mix. Windows Terminal also has keybindings, which might conflict with PSReadLine keybindings, or keybindings you want to use. I'll address that in a bit.

Getting Windows Terminal KeyBindings

The Windows Terminal key bindings are stored in the settings JSON file.

$wtProfilePath = Join-Path -Path $env:LOCALAPPDATA -ChildPath 'Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json'
$wtProfile = Get-Content $wtProfilePath | ConvertFrom-Json

The keybinding settings is very simple.

PS C:\> $wtProfile.keybindings

id                            keys
--                            ----
User.splitPane.5B23D113       ctrl+shift+comma
User.sendInput.58CEF08D       ctrl+alt+w
User.sendInput.ABD01282       ctrl+t
User.paste                    ctrl+p
User.copy.644BA8F2            ctrl+c
User.splitPane.AEAAD8C0       ctrl+alt+o
User.newTab.47BA4305          ctrl+alt+;
User.newTab.B1939200          ctrl+shift+u
User.openTabColorPicker       ctrl+/
User.splitPane.A6751878       ctrl+shift+s
User.find                     ctrl+shift+f
User.splitPane.1E0C8766       ctrl+shift+period
User.sendInput.OutputEncoding ctrl+e
Want to read the full issue?
GitHub Bluesky LinkedIn Mastodon https://jdhitsoluti…
Powered by Buttondown, the easiest way to start and grow your newsletter.