PowerShell / PSReadLine

A bash inspired readline implementation for PowerShell
BSD 2-Clause "Simplified" License
3.7k stars 294 forks source link

`SmartInsertQuote` example from README.md currently not working? #3423

Closed Hrxn closed 2 years ago

Hrxn commented 2 years ago

Prerequisites

Issue summary

PS D:\Temp>
> Set-PSReadLineKeyHandler -Chord 'Ctrl+d','Ctrl+x' `
>                          -BriefDescription SmartInsertQuote `
>                          -LongDescription "Insert paired quotes if not already on a quote" `
>                          -ScriptBlock {
>     param($key, $arg)
>
>     $line = $null
>     $cursor = $null
>     [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
>
>     if ($line[$cursor] -eq $key.KeyChar) {
>         # Just move the cursor
>         [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1)
>     }
>     else {
>         # Insert matching quotes, move cursor to be in between the quotes
>         [Microsoft.PowerShell.PSConsoleReadLine]::Insert("$($key.KeyChar)" * 2)
>         [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
>         [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor - 1)
>     }
> }
PS D:\Temp>
PS D:\Temp>
PS D:\Temp> An exception occurred in custom key handler, see $error for more information: Index was outside the bounds of the array.
PS D:\Temp> An exception occurred in custom key handler, see $error for more information: Index was outside the bounds of the array.

PS D:\Temp> $error

OperationStopped:
Line |
  12 |      if ($line[$cursor] -eq $key.KeyChar) {
     |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Index was outside the bounds of the array.

PS Version

PS D:\Temp> $PSVersionTable

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

PS D:\Temp>

Windows 10 build version: 19043.1889

I'm aware that the example actually uses 'Oem7','Shift+Oem7' as parameter for chord, as I understand these keys are dependent on the keyboard layout. I assume this is supposed to be ' and " on an EN-US keyboard? I tried to change my input method with the usual switcher in the system tray, but this did not change anything for me, it would simply insert one single quote char (or double quote) and nothing more. Changing the key binding to the example above triggers the error for me..

Could very well be a locale specific issue, but maybe someone can try to reproduce?

Hrxn commented 2 years ago

Whoops, forgot this:

PS D:\Temp> Get-Module

ModuleType Version    PreRelease Name                                ExportedCommands
---------- -------    ---------- ----                                ----------------
Manifest   7.0.0.0               Microsoft.PowerShell.Management     {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty…}
Manifest   7.0.0.0               Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object…}
Script     2.1.0                 PSReadLine                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PSReadLineKeyHandler, Set-PSReadL…

PS D:\Temp>
daxian-dbw commented 2 years ago

That example is outdated. The key chord parsing was changed in v2.0, and now you just need -Chord '"',"'" instead of Oem7.

daxian-dbw commented 2 years ago

Close as fixed in #3424

Hrxn commented 2 years ago

Well, yes, but that's why I changed the key chord in my example from my original post, to be sure that the key binding activates correctly.

And I still get the same error.. Here, copy and pasted the example from README.md:

PS D:\Temp> # Test dir is empty
PS D:\Temp> ls -fo
PS D:\Temp> # pasting sample now
PS D:\Temp>
>> Set-PSReadLineKeyHandler -Chord '"',"'" `
>>                          -BriefDescription SmartInsertQuote `
>>                          -LongDescription "Insert paired quotes if not already on a quote" `
>>                          -ScriptBlock {
>>     param($key, $arg)
>>
>>     $line = $null
>>     $cursor = $null
>>     [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
>>
>>     if ($line[$cursor] -eq $key.KeyChar) {
>>         # Just move the cursor
>>         [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1)
>>     }
>>     else {
>>         # Insert matching quotes, move cursor to be in between the quotes
>>         [Microsoft.PowerShell.PSConsoleReadLine]::Insert("$($key.KeyChar)" * 2)
>>         [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
>>         [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor - 1)
>>     }
>> }
>>
PS D:\Temp> # pressing single quote key on the next line
PS D:\Temp> An exception occurred in custom key handler, see $error for more information: Index was outside the bounds of the array.
PS D:\Temp> # pressing double quote key on the next line
PS D:\Temp> An exception occurred in custom key handler, see $error for more information: Index was outside the bounds of the array.
PS D:\Temp> $error

OperationStopped:
Line |
  12 |      if ($line[$cursor] -eq $key.KeyChar) {
     |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Index was outside the bounds of the array.

OperationStopped:
Line |
  12 |      if ($line[$cursor] -eq $key.KeyChar) {
     |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Index was outside the bounds of the array.
PS D:\Temp>
Hrxn commented 2 years ago

I think I found the culprit...

Set-StrictMode -Version Latest

Bad coding practices, tsk tsk 🙄

Hrxn commented 1 year ago

@daxian-dbw Can you (or anyone else?) confirm i.e. reproduce this (in Latest StrictMode)?

Although this should probably be tracked in a new issue. Not sure, up to you guys to decide.

daxian-dbw commented 1 year ago

Thanks for pinging again. Yes, I can reproduce in the strict mode, and submitted https://github.com/PowerShell/PSReadLine/pull/3440 to fix it.