You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SHIFT+ENTER set to AddLine - line gets executed instead of a new line being added 2.0.0-beta1 #638
Thanks, I updated the template for the variable name change to $IsMacOS.
I don't think it's possible to use Shift+Enter as a key binding on non-Windows machines, the shift state is not available to applications that use the normal tty routines for reading the keyboard. You can see this by using showkey -a, it prints the same thing for Enter and Shift+Enter (this is on Linux, not sure about a Mac, I don't have access to one.)
We should just remove the binding or use another on non-Windows if there is one in common use.
Jason Shirk (@lzybkr) I'm not sure if I'm doing something wrong here... As a test I tried setting this: Set-PSReadLineKeyHandler -Key Ctrl+\ -Function AddLine
However, when I type Ctrl+\ after running that, I get this: /Users/tylerleonhardt> asdf^\^\^\^\^\^\^\^\^\
There were a couple instances of where on macOS Alt+ something, gives you a special character like:
Alt+= gives you ≠. Alt+k gives you ˚... etc and so Alt+= wouldn't trigger PossibleCompletions like it should. I also tried this with Alt+? which should run WhatIsKey but instead I get: ÷.
I'm not sure if this related to the issue I just mentioned but I hope it helps.
on macOS Alt+ something, gives you a special character
This is a system-wide feature for generating special characters on macOS, and by default it also applies to the default terminal, Terminal.app (and also iTerm 2, its popular third-party replacement).
However, you can opt out of this behavior, in which case the terminal translates Alt+{char}chords into Esc, {char}sequences.
Here's the list of usable chords with Set-PSReadlineHandler on Unix-like platforms; compiled as of PowerShell Core 7.0.0-rc.1:
Any others are likely not supported.
The limitations stem in part from how terminals work in the Unix world, with additional limitations imposed by the CoreFx [Console] API - see bottom section; Jason Shirk (@lzybkr) has started the conversation about fixing the latter in this CoreFX issue.
Control-based chords:
Chord
Comment
Control-a
Control-b
Control-c
Caveat: handler not effective while a command is running
Control-d
Caveat: users may expect this to end interactive input
Control-e
Control-f
Control-g
Control-k
Control-l
Control-n
Control-o
Control-p
Control-q
Control-r
Control-s
Control-t
Control-u
Control-v
Control-w
Control-x
Control-y
Control-z
Caveat: if running via bash, preempted by the latter's send-to-background feature
Note:
You can add Alt to these cords.
You cannot add Shift - using Shift is effectively ignored (behaves as if it hadn't been pressed).
Note the absence of punctuation-based chords.
Alt-based chords:
Chord
Comment
Alt-a ... Alt-z
English letters only
Alt-A ... Alt-Z
Shift variations - do not use Alt-Shift-a (Alt-Shift-A would be redundant)
Alt-1 ... Alt-9
Caveat: Shift variations not supported; they trigger even if you don't press Shift, and don't trigger when you do.
Alt-/
Curiously, this particular symbol seems to work, unlike others; no Shift support
Note:
Adding Control limits you to the chords available for Control-based chords.
Note the absence of punctuation-based chords (except for /).
Shift-only-based chords:
Except for:
redefining uppercase letters
and the combinations with modifiers Alt and Control listed above
you cannot define Shift-based key handlers on Unix.
Notably, handlers such as Shift-Enter or Shift-Backspace are not supported.
Background Information
The fundamental restrictions - which come from most Unix-like OSs running xterm-emulation terminal programs are:
Control-based chords are in effect limited to a subset of the 33 well-defined chords of caret notation - plus a few effective (but presumable accidental) aliases (see bottom); the ^ symbol is known as the caret and represents the Control key; for instance, ^A represents the chord Control+A (strictly speaking, it is the uppercaseA, but at least for letters it doesn't matter whether Shift is held down or not):
From a terminal's perspective, there are noAlt-based chords at all, but most modern terminal programs translateAlt+{char}-based chords (with some terminals on an opt-in basis, as on macOS) into Esc, {char}sequences, and programs running inside that terminal see only the resulting sequence.
That's why, in the bash world, for instance, readline definitions are expressed in terms of the latter.
Generally, only characters are reported, not key states, so that there's no separate information about whether a given modifier key was (also) held down, notably not Shift.
Additionally, a given terminal program itself may have key bindings for Control-based and/or Alt-based chords, which may preempt attempts by programs running inside these terminals to bind them.
On top of that there are the shortcomings in CoreFX's [Console]::ReadKey() implementation on Unix-like platforms, which affect PSReadLine too:
Note: I'm using lowercase letters in the chord representations below to indicate chords not involving the Shift key.
On Unix-like platforms, instead of letting programs see the translation of key chords the same way as described above - which may be a single ASCII control character or an Esc, {char}sequence - CoreFX retranslates that into a chord, as you would see it on Windows, but only for some chords:
Control-based chords
Control-based chords that translate into control characters that have dedicated keys are reflected as such in the .Key property (but the .KeyChar property also contains the corresponding control character):
Note:
These mappings do not work on Windows - there, the chord as pressed is reported.
However, _even on Unix you must define PSReadLine key handlers for these chords in terms of the resulting .Key property value, not the actual chord keys (e.g., Set-PSReadLineHandler 'Escape' ..., not Set-PSReadLineHandler 'Control-[' ...)
Control+i a.k.a ^I, which is control char. HT, corresponds to the Tab key
Control+h a.k.a ^H, which is control char. BS, corresponds to the Backspace key.
Control+[ a.k.a ^[, which is control char. ESC, corresponds to the Escape key.
Control+j a.k.a ^J, which is control char. LF (0xA) is mistakenly conflated with Control+m a.k.a ^M, which is control char. CR: both result in the .KeyChar property containing `r (i.e., CR) and .Key containing Enter:
^J should have .KeyChar value (`n), its .Key property should be J, and its .Modifier property should be Control.
* Somewhat ironically, the behavior is correct on Windows.
Control-based chords that do not work:
Control+zworks in principle, but may be preempted by bash, if pwsh happened to have been launched from it; note that Control+z has special meaning in traditional shells (not the terminal emulators themselves): in cmd.exe, it signals EOF during interactive input (copy con ...); in bash, it suspends the currently executing program and sends it to the background.
* Curiously, if not preempted, direct use of [Console]::ReadKey() ignores the chord, but PSReadLine does see it.
The remaining punctuation-based chords do not work, either:
Control+@ ... seen as just @
Control+\ ... seen as just \
Control+] ... seen as just ]
Control+^ ... seen as control char. 0x1e, which prints as ^^; you can't define a PSReadLine key handler for that.
Control+_ ... seen as just _
Control+? ... seen as Backspace(!)
Curiously, direct use of [Console]::ReadKey() passes the control character correctly in the .KeyChar property (except for ^@, where it is 0), but fails to populate the .Key and .Modifier properties (both 0, except for ^?, where it is Backspace)
Redefining Control+c (probably not a good idea) isn't effective while a command is running; you get the default cancel-the-running-operation functionality then (if run [console]::TreatControlCAsInput = $true first, you lose the cancel-the-running-operation functionality altogether). In other words: you can only redefine Control+c for command-line editing.
(English) letter and digit-basedAlt-based chords, including uppercase variants, are correctly translated, and behave as on Windows.
By contrast, symbol-/punctuation-based Alt chords (e.g., Alt+') do appear to arrive as their raw Esc, {char}sequences, which [Console]::ReadKey() and therefore PSReadLine cannot handle: [Console]::ReadKey() only reports the Esc keypress, not the following {char}.
Curiously, Alt-/ is an exception.
Shift-only-based chords:
As stated, Unix terminals report characters, not key states, so there is no separate information about the state of the Shift key.
CoreFx infers that Shift was pressed for uppercase letters, and puts the value Shift in the .Modifiers property of the Sytem.ConsoleInfo instance returned, but in no other cases.
Therefore, defining handlers for chords such as Shift-Enter is fundamentally unsupported - they never trigger on Unix.
To test if chords work on Unix-like platforms, run something like the following from PowerShell:
# Alt-'a'..'z'+'1'..'9'|% {
Set-PSReadLineKeyHandler"alt-$_" ([scriptblock]::Create("Write-Host -NoNewline 'alt-$_!'"))
}
# Ctrl- (not all of them will work)'a'..'z'|% {
Set-PSReadLineKeyHandler"ctrl-$_" ([scriptblock]::Create("Write-Host -NoNewline 'ctrl-$_!'"))
}
@tylerl0706: Glad it was helpful; feel free to close this issue (depending on what will and won't get fixed, parts of my previous post will hopefully at least make it into PSReadLine's read-me / Get-Help about_PSReadLine).
Activity
lzybkr commentedon Mar 1, 2018
Thanks, I updated the template for the variable name change to
$IsMacOS.I don't think it's possible to use
Shift+Enteras a key binding on non-Windows machines, the shift state is not available to applications that use the normal tty routines for reading the keyboard. You can see this by usingshowkey -a, it prints the same thing forEnterandShift+Enter(this is on Linux, not sure about a Mac, I don't have access to one.)We should just remove the binding or use another on non-Windows if there is one in common use.
TylerLeonhardt commentedon Mar 1, 2018
Jason Shirk (@lzybkr) I'm not sure if I'm doing something wrong here... As a test I tried setting this:
Set-PSReadLineKeyHandler -Key Ctrl+\ -Function AddLineHowever, when I type
Ctrl+\after running that, I get this:/Users/tylerleonhardt> asdf^\^\^\^\^\^\^\^\^\Am I doing something wrong?
lzybkr commentedon Mar 1, 2018
No, that looks like a bug.
TylerLeonhardt commentedon Mar 1, 2018
There were a couple instances of where on macOS Alt+ something, gives you a special character like:
Alt+=gives you≠.Alt+kgives you˚... etc and soAlt+=wouldn't trigger PossibleCompletions like it should. I also tried this withAlt+?which should run WhatIsKey but instead I get:÷.I'm not sure if this related to the issue I just mentioned but I hope it helps.
lzybkr commentedon Mar 1, 2018
I'll need help on stuff like that - it looks like it differs from Linux and I don't have access to a Mac.
mklement0 commentedon Apr 12, 2018
@tylerl0706:
This is a system-wide feature for generating special characters on macOS, and by default it also applies to the default terminal,
Terminal.app(and alsoiTerm 2, its popular third-party replacement).However, you can opt out of this behavior, in which case the terminal translates Alt+{char} chords into Esc, {char} sequences.
See #529 (comment) for how to opt out.
TylerLeonhardt commentedon Apr 13, 2018
Michael Klement (@mklement0) that worked like a charm.
I have it set to
Esc+and was able to do:TylerLeonhardt commentedon Apr 13, 2018
Note:
has some strange behavior along with:
as I mentioned above.
I wonder if there's a problem with using
\mklement0 commentedon Apr 15, 2018
Here's the list of usable chords with
Set-PSReadlineHandleron Unix-like platforms; compiled as of PowerShell Core 7.0.0-rc.1:[Console]API - see bottom section; Jason Shirk (@lzybkr) has started the conversation about fixing the latter in this CoreFX issue.Control-based chords:
Control-aControl-bControl-cControl-dControl-eControl-fControl-gControl-kControl-lControl-nControl-oControl-pControl-qControl-rControl-sControl-tControl-uControl-vControl-wControl-xControl-yControl-zbash, preempted by the latter's send-to-background featureNote:
Altto these cords.Shift- using Shift is effectively ignored (behaves as if it hadn't been pressed).Alt-based chords:
Alt-a...Alt-zAlt-A...Alt-ZAlt-Shift-a(Alt-Shift-Awould be redundant)Alt-1...Alt-9Alt-/Note:
Controllimits you to the chords available for Control-based chords./).Shift-only-based chords:
Except for:
AltandControllisted aboveyou cannot define
Shift-based key handlers on Unix.Notably, handlers such as
Shift-EnterorShift-Backspaceare not supported.Background Information
The fundamental restrictions - which come from most Unix-like OSs running
xterm-emulation terminal programs are:Control-based chords are in effect limited to a subset of the 33 well-defined chords of caret notation - plus a few effective (but presumable accidental) aliases (see bottom); the
^symbol is known as the caret and represents the Control key; for instance,^Arepresents the chord Control+A (strictly speaking, it is the uppercaseA, but at least for letters it doesn't matter whether Shift is held down or not):(0x0) NUL/^Athrough(0x1f) US/^_, plus(0x7F) DEL/^?) and programs running inside that terminal see only the resulting control character.From a terminal's perspective, there are no Alt-based chords at all, but most modern terminal programs translate Alt+{char}-based chords (with some terminals on an opt-in basis, as on macOS) into Esc, {char} sequences, and programs running inside that terminal see only the resulting sequence.
That's why, in the
bashworld, for instance,readlinedefinitions are expressed in terms of the latter.Generally, only characters are reported, not key states, so that there's no separate information about whether a given modifier key was (also) held down, notably not Shift.
Additionally, a given terminal program itself may have key bindings for Control-based and/or Alt-based chords, which may preempt attempts by programs running inside these terminals to bind them.
On top of that there are the shortcomings in CoreFX's
[Console]::ReadKey()implementation on Unix-like platforms, which affect PSReadLine too:Note: I'm using lowercase letters in the chord representations below to indicate chords not involving the Shift key.
On Unix-like platforms, instead of letting programs see the translation of key chords the same way as described above - which may be a single ASCII control character or an Esc, {char} sequence - CoreFX retranslates that into a chord, as you would see it on Windows, but only for some chords:
Control-based chords
Control-based chords that translate into control characters that have dedicated keys are reflected as such in the
.Keyproperty (but the.KeyCharproperty also contains the corresponding control character):Note:
.Keyproperty value, not the actual chord keys (e.g.,Set-PSReadLineHandler 'Escape' ..., notSet-PSReadLineHandler 'Control-[' ...)Control+i a.k.a
^I, which is control char.HT, corresponds to the Tab keyControl+h a.k.a
^H, which is control char.BS, corresponds to the Backspace key.Control+[ a.k.a
^[, which is control char.ESC, corresponds to the Escape key.Control+j a.k.a
^J, which is control char.LF(0xA) is mistakenly conflated with Control+m a.k.a^M, which is control char.CR: both result in the.KeyCharproperty containing`r(i.e.,CR) and.KeycontainingEnter:^Jshould have.KeyCharvalue (`n), its.Keyproperty should beJ, and its.Modifierproperty should beControl.* Somewhat ironically, the behavior is correct on Windows.
Control-based chords that do not work:
Control+z works in principle, but may be preempted by
bash, ifpwshhappened to have been launched from it; note that Control+z has special meaning in traditional shells (not the terminal emulators themselves): incmd.exe, it signals EOF during interactive input (copy con ...); inbash, it suspends the currently executing program and sends it to the background.* Curiously, if not preempted, direct use of
[Console]::ReadKey()ignores the chord, but PSReadLine does see it.The remaining punctuation-based chords do not work, either:
@\]0x1e, which prints as^^; you can't define a PSReadLine key handler for that._[Console]::ReadKey()passes the control character correctly in the.KeyCharproperty (except for^@, where it is0), but fails to populate the.Keyand.Modifierproperties (both0, except for^?, where it isBackspace)Redefining Control+c (probably not a good idea) isn't effective while a command is running; you get the default cancel-the-running-operation functionality then (if run
[console]::TreatControlCAsInput = $truefirst, you lose the cancel-the-running-operation functionality altogether). In other words: you can only redefine Control+c for command-line editing.Alt-based chords
CoreFX tries to translate Esc, {char} sequences , as reported by the terminal emulator, back into Alt+{char}-based chords, but not consistently:
(English) letter and digit-based Alt-based chords, including uppercase variants, are correctly translated, and behave as on Windows.
By contrast, symbol-/punctuation-based Alt chords (e.g., Alt+') do appear to arrive as their raw Esc, {char} sequences, which
[Console]::ReadKey()and therefore PSReadLine cannot handle:[Console]::ReadKey()only reports the Esc keypress, not the following{char}.Shift-only-based chords:
As stated, Unix terminals report characters, not key states, so there is no separate information about the state of the Shift key.
CoreFx infers that Shift was pressed for uppercase letters, and puts the value
Shiftin the.Modifiersproperty of theSytem.ConsoleInfoinstance returned, but in no other cases.Therefore, defining handlers for chords such as
Shift-Enteris fundamentally unsupported - they never trigger on Unix.To test if chords work on Unix-like platforms, run something like the following from PowerShell:
TylerLeonhardt commentedon Apr 17, 2018
Thank you so much for all the awesome information!
We can probably close this issue in favor of the issue in CoreFX and the known limitations.
Thanks again for the thorough explanation!
mklement0 commentedon Apr 17, 2018
@tylerl0706: Glad it was helpful; feel free to close this issue (depending on what will and won't get fixed, parts of my previous post will hopefully at least make it into PSReadLine's read-me /
Get-Help about_PSReadLine).