mikemaccana
mikemaccana

Reputation: 123610

Is it possible to add a keyboard shortcut to Powershell?

I've switched to Powershell after a couple of decades of bash, and after some configuring of my profile (and adding PSCX, openssl and a few other tools) I'm generally happy.

One thing I miss from bash:

mkdir some-very-long-dir-name
cd (hit ESC then hit _ on the keyboard)

Escape underscore is bash for 'last item on the previous command'. It's super useful - in this chase I didn't have to type out the very long directory name.

Is it possible to add keyboard shortcuts to powershell? How?

I'm using ConEmu as my terminal if that matters.

Upvotes: 4

Views: 2788

Answers (2)

mikemaccana
mikemaccana

Reputation: 123610

Short answer:

 Set-PSReadlineKeyHandler -Key 'Escape,_' -Function YankLastArg

Longer explanation:

Thanks to @davidbrabant and @TheIncorrigible1 for pointing to PSReadLine: it's not the answer itself, but understanding how PSReadLine works is the key to solving this.

Although vi is the default editor on every Linux distribution, bash's default is emacs editing mode. From the bash docs:

In order to switch interactively between emacs and vi editing modes, use the ‘set -o emacs’ and ‘set -o vi’ commands (see The Set Builtin). The Readline default is emacs mode.

Which means 'escape underscore' comes from emacs.

Oddly, PSReadLine, unlike bash, does't use emacs mode by default. From the PSREADLine docs:

To use Emacs key bindings, you can use: Set-PSReadlineOption -EditMode Emacs

It's not very explicit, but that means another mode is default. Confirming that, running:

get-PSReadlineOption

Returns:

EditMode                               : Vi

So there are two solutions:

Solution 1: change mode

Set-PSReadlineOption -EditMode Emacs

You can see the effect with Get-PSReadlineKeyHandler includes the standard escape underscore shortcut:

Escape,_         YankLastArg                   Copy the text of the last argument to the input

Escape underscore now works.

Solution 2: add the shortcut to your existing mode

Instead of changing mode (it turns out I like vi keybindings!), you can also run:

 Set-PSReadlineKeyHandler -Key 'Escape,_' -Function YankLastArg

To add it to your existing mode.

Upvotes: 6

Maximilian Burszley
Maximilian Burszley

Reputation: 19694

An alternative to your ESC+_ solution, the PowerShell automatic variable $$ contains the same information without the need for PSReadLine (pre-v5.0 or without the module installed).

PS C:\> Get-ChildItem -Path 'C:\'

...

PS C:\> $$

C:\

You can also capture the command used with the $^ variable:

PS C:\> $^

get-childitem

Upvotes: 3

Related Questions