Description
Prerequisites
- Write a descriptive title.
- Make sure you are able to repro it on the latest released version
- Search the existing issues, especially the pinned issues.
Exception report
ErrorRecord : Exception calling "InvokePrompt" with "0" argument(s): "The value must be greater than or equal to zero and less than the console's buffer size in that dimension. (Parameter 'top')
Actual value was -5."
WasThrownFromThrowStatement : False
TargetSite : Void CheckActionPreference(System.Management.Automation.Language.FunctionContext, System.Exception)
Message : Exception calling "InvokePrompt" with "0" argument(s): "The value must be greater than or equal to zero and less than the console's buffer size in that dimension. (Parameter 'top')
Actual value was -5."
Data : {[System.Management.Automation.Interpreter.InterpretedFrameInfo, System.Management.Automation.Interpreter.InterpretedFrameInfo[]]}
InnerException : System.ArgumentOutOfRangeException: The value must be greater than or equal to zero and less than the console's buffer size in that dimension. (Parameter 'top')
Actual value was -5.
at System.Console.SetCursorPosition(Int32 left, Int32 top)
at Microsoft.PowerShell.PSConsoleReadLine.InvokePrompt(Nullable`1 key, Object arg)
at CallSite.Target(Closure, CallSite, Type)
HelpLink :
Source : System.Management.Automation
HResult : -2146233087
StackTrace : at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.ScriptBlock.InvokeWithPipeImpl(ScriptBlockClauseToInvoke clauseToInvoke, Boolean createLocalScope, Dictionary`2 functionsToDefine, List`1 variablesToDefine, ErrorHandlingBehavior
errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Object[] args)
at System.Management.Automation.ScriptBlock.InvokeWithPipe(Boolean useLocalScope, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo
invocationInfo, Boolean propagateAllExceptionsToTop, List`1 variablesToDefine, Dictionary`2 functionsToDefine, Object[] args)
at Microsoft.PowerShell.PSConsoleReadLine.<>c__DisplayClass258_0.<SetKeyHandler>g__HandlerWrapper|0(Nullable`1 k, Object arg)
Screenshot
N/A
Environment data
PS Version: 7.5.1
PS HostName: ConsoleHost (Windows Terminal)
PSReadLine Version: 2.3.6
PSReadLine EditMode: Windows
OS: 10.0.26100.1 (WinBuild.160101.0800)
BufferWidth: 316
BufferHeight: 79
Steps to reproduce
# Note - This is not specific to the enter key, any call to InvokePrompt where the start of the prompt is outside the buffer will trigger the exception.
Set-PSReadLineKeyHandler -Key Enter -BriefDescription 'InvokePromptRepro' -ScriptBlock { [Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt(); [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine(); }
$long = { # add newlines until this line is no longer visible
# ...
} # Then hit Enter (or whatever key you bound to call InvokePrompt
An exception occurred in custom key handler, see $error for more information: Exception calling "InvokePrompt" with "0" argument(s): "The value must be greater than or equal to zero and less than the console's buffer size in that dimension. (Parameter 'top')
Actual value was -1."
Expected behavior
A caller would normally expect InvokePrompt to update the prompt. Ideally PSReadLine can update the prompt but as I understand it terminal/modern console hosting makes the screen buffer match the window size and as such does not allow setting a cursor position outside the window buffer.
- When InvokePrompt is called without a specific Y position (i.e. arg == null) I would expect noop/immediate return.
- When InvokePrompt is called with a Y position I would expect an ArgumentOutOfRangeException for negative Y values which is current behavior. The current exception bubbles up from console.SetCursorPosition to the caller but InvokePrompt should probably test that arg >= 0 and throw the exception directly.
The reason I'm saying it should be a noop is that _initialY is private and the caller has no idea where PSReadLine is going to go when they call InvokePrompt so the method should behave similarly to the checks added to Render when the user attempts to navigate out of the buffer :
PSReadLine/PSReadLine/Render.cs
Line 1163 in 9b6a47d
Actual behavior
Exception is thrown whenever InvokePrompt is called and the prompt is outside the buffer (either off-screen in windows terminal, or above the buffer in any other console host).