Skip to content

"Ctrl+[" is not bondable as a key chord in PSReadLine #906

Open
@gwojan

Description

@gwojan

Environment data

AppVeyor Build: 1.0.553

PS version: 5.1.17763.316
PSReadline version: 2.0.0-beta4, **AppVeyor Build: 1.0.553**
os: 10.0.17763.1 (WinBuild.160101.0800)
PS file version: 10.0.17763.1 (WinBuild.160101.0800)

and

PS version: 6.2.0
PSReadline version: 2.0.0-beta4, **AppVeyor Build: 1.0.553**
os: 10.0.17763.1 (WinBuild.160101.0800)
PS file version: 6.2.0

Steps to reproduce or exception report

Enable PSReadLine vi-mode
While in insert-mode press Ctrl+[ and prior behavior was to change to command-mode
Currently, ^[ is rendered in the console and PSReadLine remains in insert-mode.

Activity

gwojan

gwojan commented on Apr 30, 2019

@gwojan
Author

So, just to throw another wrinkle, pressing Ctrl+[ in the PowerShell Integrated Console in VSCode, PowerShell Preview 2.0.2 works as expected.

PS version: 6.2.0
PSReadline version: 2.0.0-beta4, **AppVeyor Build: 1.0.553**
os: 10.0.17763.1 (WinBuild.160101.0800)
PS file version: 6.2.0

Keep in mind this IS NOT the PSReadLine included with the PowerShell Preview Extension -- it's the same version being used in other "terminals".

daxian-dbw

daxian-dbw commented on Jun 3, 2019

@daxian-dbw
Member

@gwojan Did Ctrl+[ ever work on Windows in the pwsh console with the VI mode?
Both 2.0.0-beta.3 and 2.0.0-beta.4 work as you expect (change to command mode) in pwsh on Linux, but on Windows, both don't work while the beta.4 PSReadLine renders ^[ (Ctrl+[ doesn't work in beta.2 either).

gwojan

gwojan commented on Jun 3, 2019

@gwojan
Author

@daxian-dbw yes, absolutely it worked on Windows PowerShell and pwsh.exe. As a matter of fact, it still works in the VSCode PowerShell Integrated Console just not the standard Windows Console.

daxian-dbw

daxian-dbw commented on Jun 3, 2019

@daxian-dbw
Member

@gwojan Then it may be a regression that happened way back ... I just tried with 2.0.0-beta.2, and it doesn't work. Which version did it work for you?

gwojan

gwojan commented on Jun 3, 2019

@gwojan
Author

@daxian-dbw The build that I pulled from AppVeyor (Build: 1.0.553) that broke things for me was documented in the original report.

If you'd like I can try to reinstall some of the older builds to identify a working one. 😃

daxian-dbw

daxian-dbw commented on Jun 4, 2019

@daxian-dbw
Member

Never mind if you cannot remember the working version that you used before. I will search back to find it out.

gwojan

gwojan commented on Jun 4, 2019

@gwojan
Author

@daxian-dbw The last working build I have from AppVeyor is 1.0.508 files dated 2/22/2019. The PSReadLine.psd1 has this tagged as beta3.

I also have:
Set-PSReadLineKeyHandler -Chord 'Ctrl+[' -Function ViCommandMode in my profile.

The next version that I still have on my system that actually breaks Ctrl+[ is 1.0.540 files dated 4/17/2019.

gwojan

gwojan commented on Jun 7, 2019

@gwojan
Author

@daxian-dbw I just pulled build 1.0.15 from AppVeyor and confirmed the Ctrl+[ binding works again in Windows PowerShell 5.1, PowerShell 6.2 and PowerShell 7. My fingers thank you immensely! 😀 👍

daxian-dbw

daxian-dbw commented on Jun 10, 2019

@daxian-dbw
Member

@gwojan glad it worked for you, but the PR is still in review and not merged yet, so let's keep this issue open for now.

gwojan

gwojan commented on Jun 10, 2019

@gwojan
Author

Thanks @daxian-dbw. 😄 I just noticed this also fixes another issue I was having and forgot to open an issue.

Set-PSReadLineKeyHandler -Key 'Ctrl+{' -Function DeleteLine

This now works like <ESC>S to clear the current line.

added this to the 2.0.0-Consider milestone on Jun 18, 2019

4 remaining items

CurtisDyer

CurtisDyer commented on Jul 28, 2020

@CurtisDyer

I can confirm I am having the same issue with 2.1.0-beta2. I have the issue in Windows Terminal 1.1, 1.2 Preview, and conhost environments (PS 5.1 and PS 7.0.3).

However, it does work in VS Code terminal (PS 5.1).

Windows Version: 1909, Build 18363.959

❯ $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.0.3
PSEdition                      Core
GitCommitId                    7.0.3
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

❯ Get-Module -Name psreadline

ModuleType Version    PreRelease Name                                ExportedCommands
---------- -------    ---------- ----                                ----------------
Script     2.1.0      beta2      PSReadLine                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, …

❯ Set-PSReadLineOption -EditMode vi
❯ Set-PSReadLineKeyHandler -Chord 'ctrl+[' -Function ViCommandMode
❯ abc^[^[^[^C
removed this from the 2.1.0-Consider milestone on Jul 1, 2021
parkovski

parkovski commented on Sep 10, 2021

@parkovski
Contributor

Current workaround is to find the OEM scan code for your [ key and use the name for it from System.ConsoleKey, it works for me as Ctrl+Oem4.

CurtisDyer

CurtisDyer commented on Sep 10, 2021

@CurtisDyer

Current workaround is to find the OEM scan code for your [ key and use the name for it from System.ConsoleKey, it works for me as Ctrl+Oem4.

This workaround resolved the issue for me. Thank you for sharing!

changed the title [-]Ctrl+[ in vi insert mode no longer acts as escape changing to command-mode[/-] [+]"Ctrl+[" is not bondable as a key chord in PSReadLine[/+] on Jan 30, 2023
andyleejordan

andyleejordan commented on Jan 30, 2023

@andyleejordan
Member

I can at least shed some light on why this is so broken, or really, why it's often broken and then sometimes seemingly not broken, with no easy permanent fix. The key combination Ctrl+[ is Esc, as in, it's supposed to send ASCII code 27 just as pressing the escape key does. Historically that key chord is one and the same as the escape key. But nowadays there's a whole of lot of "things" in between the keyboard and PSReadLine finally receiving they key (I'm mostly talking about .NET's own System.Console.ReadKey implementation, but also relevant are different terminal emulators). In fact on macOS and Linux, where .NET is quite a bit "newer" and understands ASCII codes fairly well, and the terminal emulators are pretty standard, you can run [Console]::ReadKey() in PowerShell, press Ctrl+[, and you'll get:

> [Console]::ReadKey()                                                                                                      
KeyChar    Key Modifiers
-------    --- ---------
       Escape         0

So on PSReadLine's side, setting up a binding to listen the simultaneous press of the keys Ctrl and [ probably isn't going to work, because the keyboard driver won't send it, it'll send Esc. At least that behavior though is predictable and we could special case Set-PSReadLineKeyHandler -Chord 'Ctrl+[' to be understood as listening for escape.

But Windows is where the trouble especially lies, it doesn't follow the same rules. The same experiment on an up-to-date Windows with the latest Terminal app:

> [Console]::ReadKey()

KeyChar  Key Modifiers
-------  --- ---------
       Oem4   Control

Which at least explains why binding Ctrl+Oem4 works (for most people). It should be Esc, with no modifier key, but with however .NET is implemented, and however the particular Windows terminal is behaving, this does different things!

Repeating the experiment, on Windows, but this time using a terminal in VS Code (which is based off Xterm.js) instead of the Windows Terminal app, watch:

> [System.Console]::ReadKey()
KeyChar    Key Modifiers
-------    --- ---------
       Escape         0

That's right! And on Windows. But so inconsistent as to produce this bug. What gives? 🤷 There's a lot of places this could be "wrong" in different ways and therefore "fixed" and it's hard to say what's right.

  • PSReadLine could probably treat Ctrl+Oem4 as Escape on Windows, and also interpret the binding Ctrl+[ as Esc.
  • .NET could probably treat Ctrl+Oem4 as Escape on Windows
  • Windows Terminal could probably stop sending Ctrl+Oem4 and instead send Escape (like Xterm.js and every terminal you'll find on macOS and Linux)
  • And probably other things

We've been dealing with "weird" unexpected things like this due to the historical evolution of keyboard input ever since we first got Console.ReadKey() working on .NET Core so we could implement PSReadLine. It's complicated!

xdhmoore

xdhmoore commented on Jun 9, 2023

@xdhmoore

For me the Ctrl+Oem4-based key handler works when I am in insert mode. But when I am in normal or command mode or whatever it's called, the Ctrl+[ chord outputs ^[ to the terminal.

I'm wondering if the ViCommandMode function passes through the key command when you are already in command mode. This seems like it could be related to the behavior of Esc. When I press Esc in insert mode, it changes me to command mode. But when I press it in command mode, it issues a beep. The beep is the same behavior as Vim, but I wonder if the layering here that works for Escape is not working correctly for Ctrl+Oem4. Just a theory.

I'm using Windows Terminal.

Nevermind, the following addition seems to have solved it:

Set-PSReadLineKeyHandler -Chord 'Ctrl+Oem4' -Function Abort -ViMode Command
added
Issue-BugIt either shouldn't be doing this or needs an investigation.
Area-KeyHandlersLabel for issues related to key handlers
on Oct 30, 2023
CNLHC

CNLHC commented on Sep 25, 2024

@CNLHC

Set-PSReadLineKeyHandler -Chord 'Ctrl+Oem4' -Function ViCommandMode
works for me

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

Metadata

Metadata

Assignees

Labels

Area-KeyHandlersLabel for issues related to key handlersIssue-BugIt either shouldn't be doing this or needs an investigation.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @daxian-dbw@CurtisDyer@softmoth@parkovski@andyleejordan

    Issue actions

      "Ctrl+[" is not bondable as a key chord in PSReadLine · Issue #906 · PowerShell/PSReadLine