Skip to content
Merged
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 35 additions & 16 deletions PSReadLine/Completion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@lzybkr lzybkr Aug 20, 2018

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 + 1 to write out a single newline?

Based on the comment in EnsureMenuAndInputIsVisible, I could see that + 1 being 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 pass rows:1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found calling EnsureMenuAndInputIsVisible can 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(), after console.SetCursorPosition(0, this.Top); . It seems work fine for all cases now. Thanks.

& {Get-C
abc1
abc2
abc3
}

}

console.CursorVisible = false;
console.SaveCursor();
console.SetCursorPosition(0, this.Top);

var bufferWidth = console.BufferWidth;
Expand Down Expand Up @@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this block necessary? InvokePrompt is called immediately after the call site that passes menuSelect: false and InvokePrompt is correctly updating these fields.

I tested briefly with these commented out and didn't see any problems.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. We do not need it. I added it because I used Console.Write("\n") before. Removed it now. Thanks.

_singleton._initialX = console.CursorLeft;
_singleton._initialY = console.CursorTop;
_singleton._previousRender = _initialPrevRender;
}
}

public void Clear()
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down