-
Notifications
You must be signed in to change notification settings - Fork 320
Fix System.ArgumentOutOfRangeException while get-tab #704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
5d11156
6aedc7d
c08e171
3c72b87
a395af3
33b2ba6
2f57fe5
88976f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -464,13 +464,13 @@ private class Menu | |
| internal CompletionResult CurrentMenuItem => MenuItems[CurrentSelection]; | ||
| internal int CurrentSelection; | ||
|
|
||
| void EnsureMenuAndInputIsVisible(IConsole console, int tooltipLineCount) | ||
| void EnsureMenuAndInputIsVisible(IConsole console, int tooltipLineCount, int rows) | ||
| { | ||
| // The +1 lets us write a newline after the last row, which isn't strictly necessary | ||
| // It does help with: | ||
| // * Console selecting multiple lines of text | ||
| // * Adds a little extra space underneath the menu | ||
| var bottom = this.Top + this.Rows + tooltipLineCount + 1; | ||
| var bottom = this.Top + rows + tooltipLineCount + 1; | ||
| if (bottom > console.BufferHeight) | ||
| { | ||
| var toScroll = bottom - console.BufferHeight; | ||
|
|
@@ -483,16 +483,24 @@ void EnsureMenuAndInputIsVisible(IConsole console, int tooltipLineCount) | |
| } | ||
| } | ||
|
|
||
| public void DrawMenu(Menu previousMenu) | ||
| public void DrawMenu(Menu previousMenu, bool menuSelect) | ||
| { | ||
| IConsole console = Singleton._console; | ||
|
|
||
| // Move cursor to the start of the first line after our input. | ||
| this.Top = Singleton.ConvertOffsetToPoint(Singleton._buffer.Length).Y + 1; | ||
| EnsureMenuAndInputIsVisible(console, tooltipLineCount: 0); | ||
| if (menuSelect) | ||
| { | ||
| EnsureMenuAndInputIsVisible(console, tooltipLineCount: 0, rows:this.Rows); | ||
|
|
||
| console.CursorVisible = false; | ||
| console.SaveCursor(); | ||
| } | ||
| else | ||
| { | ||
| EnsureMenuAndInputIsVisible(console, tooltipLineCount: 0, rows:0); | ||
| } | ||
|
|
||
| console.CursorVisible = false; | ||
| console.SaveCursor(); | ||
| console.SetCursorPosition(0, this.Top); | ||
|
|
||
| var bufferWidth = console.BufferWidth; | ||
|
|
@@ -532,8 +540,18 @@ public void DrawMenu(Menu previousMenu) | |
| } | ||
| } | ||
|
|
||
| console.RestoreCursor(); | ||
| console.CursorVisible = true; | ||
| if (menuSelect) | ||
| { | ||
| console.RestoreCursor(); | ||
| console.CursorVisible = true; | ||
| } | ||
| else | ||
| { | ||
| // Update the cursor coordinates after showing the menu. | ||
|
||
| _singleton._initialX = console.CursorLeft; | ||
| _singleton._initialY = console.CursorTop; | ||
| _singleton._previousRender = _initialPrevRender; | ||
| } | ||
| } | ||
|
|
||
| public void Clear() | ||
|
|
@@ -591,15 +609,16 @@ public void UpdateMenuSelection(int selectedItem, bool select, bool showTooltips | |
| } | ||
| } | ||
|
|
||
| if (BufferLines + Rows + toolTipLines > console.WindowHeight) | ||
| // The +1 is for a new line after showing the tool tips | ||
| if ((Top + Rows + toolTipLines + 1) > console.WindowHeight) | ||
| { | ||
| showTooltips = false; | ||
| } | ||
| } | ||
|
|
||
| if (showTooltips) | ||
| { | ||
| EnsureMenuAndInputIsVisible(console, toolTipLines); | ||
| EnsureMenuAndInputIsVisible(console, toolTipLines, this.Rows); | ||
| } | ||
|
|
||
| console.SaveCursor(); | ||
|
|
@@ -742,8 +761,8 @@ private void PossibleCompletionsImpl(CommandCompletion completions, bool menuSel | |
| } | ||
| else | ||
| { | ||
| menu.DrawMenu(null); | ||
| InvokePrompt(key: null, arg: menu.Top + menu.Rows); | ||
| menu.DrawMenu(null, menuSelect:false); | ||
| InvokePrompt(key: null, arg: _console.CursorTop); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -790,7 +809,7 @@ private void MenuCompleteImpl(Menu menu, CommandCompletion completions) | |
| var userInitialCompletionLength = userCompletionText.Length; | ||
|
|
||
| completions.CurrentMatchIndex = 0; | ||
| menu.DrawMenu(null); | ||
| menu.DrawMenu(null, menuSelect:true); | ||
|
|
||
| bool processingKeys = true; | ||
| int previousSelection = -1; | ||
|
|
@@ -821,7 +840,7 @@ private void MenuCompleteImpl(Menu menu, CommandCompletion completions) | |
| if (topAdjustment != 0) | ||
| { | ||
| menu.Top += topAdjustment; | ||
| menu.DrawMenu(null); | ||
| menu.DrawMenu(null, menuSelect:true); | ||
| } | ||
| if (topAdjustment > 0) | ||
| { | ||
|
|
@@ -898,7 +917,7 @@ private void MenuCompleteImpl(Menu menu, CommandCompletion completions) | |
| { | ||
| var newMenu = menuStack.Pop(); | ||
|
|
||
| newMenu.DrawMenu(menu); | ||
| newMenu.DrawMenu(menu, menuSelect:true); | ||
| previousSelection = -1; | ||
|
|
||
| menu = newMenu; | ||
|
|
@@ -960,7 +979,7 @@ private void MenuCompleteImpl(Menu menu, CommandCompletion completions) | |
| { | ||
| var newMenu = CreateCompletionMenu(newMatches); | ||
|
|
||
| newMenu.DrawMenu(menu); | ||
| newMenu.DrawMenu(menu, menuSelect:true); | ||
| previousSelection = -1; | ||
|
|
||
| // Remember the current menu for when we see Backspace. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this call necessary? I suspected it wasn't and tested briefly with it removed, I didn't see any problems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. we needed it. On Windows, I do not see problem either. But on Linux the System.ArgumentOutOfRangeException occurs on the EnsureMenuAndInputIsVisible() , Singleton._initialY -= toScroll becomes negative when rows is large.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jianyunt - after resolving this comment (either removing the call or confirming it is needed), I think this PR is ready to merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lzybkr Yes we need to keep this Line https://github.com/lzybkr/PSReadLine/blob/2f57fe5091e0e0cd343b86851dc31c9bdcb2afd5/PSReadLine/Completion.cs#L501 to avoid the ArgumentOutOfRangeException exception.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you relying on the
+ 1to write out a single newline?Based on the comment in
EnsureMenuAndInputIsVisible, I could see that+ 1being removed at some point, and then the method would do nothing, right?If my understanding is correct, it would be good to have some way to ensure this problem doesn't come back if someone removes that
+ 1- a test, or maybe passrows:1.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found calling
EnsureMenuAndInputIsVisiblecan cause the ArgumentOutOfRangeException when the window is reduced to one line height or the following can cause the exception too when the window height is 5 in this case (full screen editing). Thus I changed back to use console.Write(), afterconsole.SetCursorPosition(0, this.Top);. It seems work fine for all cases now. Thanks.