mirror of
https://github.com/PowerShell/PSReadLine
synced 2026-06-08 12:12:13 +00:00
Fix three issues with the menu completion (#1946)
1. Fix menu completion to work with the predictive list view (fix #1935 -- regression introduced in 2.2.0-beta1) 2. Fix menu completion to clear lines properly when the menu top changes on re-drawing (regression introduced in 2.2.0-beta1) 3. Fix how `RightArrow`, `LeftArrow`, `UpArrow`, and `DownArrow` navigate in the menu view (enhancement)
This commit is contained in:
+112
-31
@@ -491,11 +491,18 @@ namespace Microsoft.PowerShell
|
||||
}
|
||||
}
|
||||
|
||||
bool extraPreRowsCleared = false;
|
||||
if (previousMenu != null)
|
||||
{
|
||||
if (Rows < previousMenu.Rows + previousMenu.ToolTipLines)
|
||||
{
|
||||
// Rest of the current line was erased, but the cursor was not moved to the next line.
|
||||
// If the last menu row took the whole buffer width, then the cursor could be pushed to the
|
||||
// beginning of the next line in the legacy console host (NOT in modern terminals such as
|
||||
// Windows Terminal, VSCode Terminal, or virtual-terminal-enabled console host). In such a
|
||||
// case, there is no need to move the cursor to the next line.
|
||||
//
|
||||
// If that is not the case, namely 'CursorLeft != 0', then the rest of the last menu row was
|
||||
// erased, but the cursor was not moved to the next line, so we will move the cursor.
|
||||
if (console.CursorLeft != 0)
|
||||
{
|
||||
// There are lines from the previous rendering that need to be cleared,
|
||||
@@ -504,13 +511,25 @@ namespace Microsoft.PowerShell
|
||||
}
|
||||
|
||||
Singleton.WriteBlankLines(previousMenu.Rows + previousMenu.ToolTipLines - Rows);
|
||||
extraPreRowsCleared = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if the menu has moved, we need to clear the lines under it
|
||||
if (bufferEndPoint.Y < PreviousTop)
|
||||
{
|
||||
console.BlankRestOfLine();
|
||||
// In either of the following two cases, we will need to move the cursor to the next line:
|
||||
// - if extra rows from previous menu were cleared, then we know the current line was erased
|
||||
// but the cursor was not moved to the next line.
|
||||
// - if 'CursorLeft != 0', then the rest of the last menu row was erased, but the cursor
|
||||
// was not moved to the next line.
|
||||
if (extraPreRowsCleared || console.CursorLeft != 0)
|
||||
{
|
||||
// There are lines from the previous rendering that need to be cleared,
|
||||
// so we are sure there is no need to scroll.
|
||||
MoveCursorDown(1);
|
||||
}
|
||||
|
||||
Singleton.WriteBlankLines(PreviousTop - bufferEndPoint.Y);
|
||||
}
|
||||
|
||||
@@ -614,10 +633,62 @@ namespace Microsoft.PowerShell
|
||||
RestoreCursor();
|
||||
}
|
||||
|
||||
public void MoveRight() => CurrentSelection = Math.Min(CurrentSelection + Rows, MenuItems.Count - 1);
|
||||
public void MoveLeft() => CurrentSelection = Math.Max(CurrentSelection - Rows, 0);
|
||||
public void MoveUp() => CurrentSelection = Math.Max(CurrentSelection - 1, 0);
|
||||
public void MoveDown() => CurrentSelection = Math.Min(CurrentSelection + 1, MenuItems.Count - 1);
|
||||
public void MoveRight()
|
||||
{
|
||||
int nextInSameRow = CurrentSelection + Rows;
|
||||
if (nextInSameRow <= MenuItems.Count - 1)
|
||||
{
|
||||
CurrentSelection = nextInSameRow;
|
||||
return;
|
||||
}
|
||||
|
||||
// Index of the column where 'CurrentSelection' is at, assuming columns start from left at index 0.
|
||||
int columnIndex = CurrentSelection / Rows;
|
||||
int leftmostItemInSameRow = CurrentSelection - columnIndex * Rows;
|
||||
|
||||
// Index of the row where 'leftMostItemAtSameRow' is at, assuming rows start from top at index 0.
|
||||
int rowIndex = leftmostItemInSameRow % Rows;
|
||||
|
||||
// If 'rowIndex == Rows - 1', then 'CurrentSelection' is at the rightmost position in the last row,
|
||||
// so moving-to-right again should move to the item at index 0.
|
||||
CurrentSelection = rowIndex == Rows - 1 ? 0 : leftmostItemInSameRow + 1;
|
||||
}
|
||||
|
||||
public void MoveLeft()
|
||||
{
|
||||
int previousInSameRow = CurrentSelection - Rows;
|
||||
if (previousInSameRow >= 0)
|
||||
{
|
||||
CurrentSelection = previousInSameRow;
|
||||
return;
|
||||
}
|
||||
|
||||
// Index of the row where 'CurrentSelection' is at, assuming rows start from top at index 0.
|
||||
int rowIndex = CurrentSelection % Rows;
|
||||
int leftmostItemInPreviousRow = rowIndex == 0 ? Rows - 1 : rowIndex - 1;
|
||||
|
||||
int lastItemIndex = MenuItems.Count - 1;
|
||||
// Index of the column where the last item is at, assuming columns start from left at index 0.
|
||||
int lastItemColumnIndex = lastItemIndex / Rows;
|
||||
|
||||
// Get the rightmost item in the previous row.
|
||||
CurrentSelection = leftmostItemInPreviousRow + lastItemColumnIndex * Rows;
|
||||
if (CurrentSelection > lastItemIndex)
|
||||
{
|
||||
CurrentSelection = leftmostItemInPreviousRow + (lastItemColumnIndex - 1) * Rows;
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveUp()
|
||||
{
|
||||
CurrentSelection = CurrentSelection > 0 ? CurrentSelection - 1 : MenuItems.Count - 1;
|
||||
}
|
||||
|
||||
public void MoveDown()
|
||||
{
|
||||
CurrentSelection = CurrentSelection < (MenuItems.Count - 1) ? CurrentSelection + 1 : 0;
|
||||
}
|
||||
|
||||
public void MovePageDown() => CurrentSelection = Math.Min(CurrentSelection + Rows - (CurrentSelection % Rows) - 1,
|
||||
MenuItems.Count - 1);
|
||||
public void MovePageUp() => CurrentSelection = Math.Max(CurrentSelection - (CurrentSelection % Rows), 0);
|
||||
@@ -808,9 +879,6 @@ namespace Microsoft.PowerShell
|
||||
|
||||
var userInitialCompletionLength = userCompletionText.Length;
|
||||
|
||||
completions.CurrentMatchIndex = 0;
|
||||
menu.DrawMenu(null, menuSelect:true);
|
||||
|
||||
bool processingKeys = true;
|
||||
int previousSelection = -1;
|
||||
|
||||
@@ -832,38 +900,51 @@ namespace Microsoft.PowerShell
|
||||
|
||||
ExchangePointAndMark();
|
||||
|
||||
// After replacement, the menu might be misplaced from the command line
|
||||
// getting shorter or longer.
|
||||
var endOfCommandLine = ConvertOffsetToPoint(_buffer.Length);
|
||||
var topAdjustment = (endOfCommandLine.Y + 1) - menu.Top;
|
||||
|
||||
if (topAdjustment != 0)
|
||||
if (previousSelection == -1)
|
||||
{
|
||||
menu.Top += topAdjustment;
|
||||
menu.DrawMenu(null, menuSelect:true);
|
||||
completions.CurrentMatchIndex = 0;
|
||||
menu.DrawMenu(null, menuSelect: true);
|
||||
}
|
||||
if (topAdjustment > 0)
|
||||
else
|
||||
{
|
||||
// Render did not clear the rest of the command line which flowed
|
||||
// into the menu, so we must do that here.
|
||||
menu.SaveCursor();
|
||||
_console.SetCursorPosition(endOfCommandLine.X, endOfCommandLine.Y);
|
||||
_console.Write(Spaces(_console.BufferWidth - endOfCommandLine.X));
|
||||
menu.RestoreCursor();
|
||||
}
|
||||
// After replacement, the menu might be misplaced from the command line
|
||||
// getting shorter or longer.
|
||||
var endOfCommandLine = ConvertOffsetToPoint(_buffer.Length);
|
||||
var topAdjustment = (endOfCommandLine.Y + 1) - menu.Top;
|
||||
|
||||
if (topAdjustment != 0)
|
||||
{
|
||||
menu.Top += topAdjustment;
|
||||
menu.DrawMenu(null, menuSelect: true);
|
||||
}
|
||||
if (topAdjustment > 0)
|
||||
{
|
||||
// Render did not clear the rest of the command line which flowed
|
||||
// into the menu, so we must do that here.
|
||||
menu.SaveCursor();
|
||||
_console.SetCursorPosition(endOfCommandLine.X, endOfCommandLine.Y);
|
||||
_console.Write(Spaces(_console.BufferWidth - endOfCommandLine.X));
|
||||
menu.RestoreCursor();
|
||||
}
|
||||
|
||||
if (previousSelection != -1)
|
||||
{
|
||||
if (menu.ToolTipLines > 0)
|
||||
{
|
||||
// Erase previous tooltip, taking into account if the menu moved up/down.
|
||||
WriteBlankLines(menu.Top + menu.Rows, -topAdjustment + menu.ToolTipLines);
|
||||
}
|
||||
menu.UpdateMenuSelection(previousSelection, /*select*/ false,
|
||||
/*showToolTips*/false, Options._emphasisColor);
|
||||
|
||||
menu.UpdateMenuSelection(
|
||||
previousSelection,
|
||||
select: false,
|
||||
showTooltips: false,
|
||||
Options._emphasisColor);
|
||||
}
|
||||
menu.UpdateMenuSelection(menu.CurrentSelection, /*select*/ true,
|
||||
Options.ShowToolTips, Options._emphasisColor);
|
||||
|
||||
menu.UpdateMenuSelection(
|
||||
menu.CurrentSelection,
|
||||
select: true,
|
||||
Options.ShowToolTips,
|
||||
Options._emphasisColor);
|
||||
|
||||
previousSelection = menu.CurrentSelection;
|
||||
}
|
||||
|
||||
@@ -601,6 +601,8 @@ static class PlatformWindows
|
||||
var y = CursorTop;
|
||||
|
||||
for (int i = 0; i < BufferWidth - x; i++) Console.Write(' ');
|
||||
|
||||
// Last step may result in scrolling.
|
||||
if (CursorTop != y+1) y -= 1;
|
||||
|
||||
SetCursorPosition(x, y);
|
||||
|
||||
+700
-2
@@ -1,4 +1,5 @@
|
||||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
@@ -147,7 +148,7 @@ namespace Test
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void MenuCompletions()
|
||||
public void MenuCompletions_FilterByTyping()
|
||||
{
|
||||
TestSetup(KeyMode.Cmd, new KeyHandler("Ctrl+Spacebar", PSConsoleReadLine.MenuComplete));
|
||||
|
||||
@@ -173,6 +174,678 @@ namespace Test
|
||||
));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void MenuCompletions_Navigation1()
|
||||
{
|
||||
// Test 'RightArrow' and 'LeftArrow' with the following menu:
|
||||
// Get-Many0 Get-Many3 Get-Many6 Get-Many9 Get-Many12
|
||||
// Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13
|
||||
// Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14
|
||||
|
||||
TestSetup(KeyMode.Cmd, new KeyHandler("Ctrl+Spacebar", PSConsoleReadLine.MenuComplete));
|
||||
|
||||
_console.Clear();
|
||||
Test("Get-Many0", Keys(
|
||||
"Get-Many", _.Ctrl_Spacebar,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "0", NextLine,
|
||||
TokenClassification.Selection, "Get-Many0 ",
|
||||
TokenClassification.None,
|
||||
"Get-Many3 Get-Many6 Get-Many9 Get-Many12", NextLine,
|
||||
"Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "3", NextLine,
|
||||
TokenClassification.None, "Get-Many0 ",
|
||||
TokenClassification.Selection, "Get-Many3 ",
|
||||
TokenClassification.None,
|
||||
"Get-Many6 Get-Many9 Get-Many12", NextLine,
|
||||
"Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "6", NextLine,
|
||||
TokenClassification.None, "Get-Many0 Get-Many3 ",
|
||||
TokenClassification.Selection, "Get-Many6 ",
|
||||
TokenClassification.None, "Get-Many9 Get-Many12", NextLine,
|
||||
"Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "9", NextLine,
|
||||
TokenClassification.None, "Get-Many0 Get-Many3 Get-Many6 ",
|
||||
TokenClassification.Selection, "Get-Many9 ",
|
||||
TokenClassification.None, "Get-Many12", NextLine,
|
||||
"Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "12", NextLine,
|
||||
TokenClassification.None, "Get-Many0 Get-Many3 Get-Many6 Get-Many9 ",
|
||||
TokenClassification.Selection, "Get-Many12 ", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "1", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Many0 Get-Many3 Get-Many6 Get-Many9 Get-Many12", NextLine,
|
||||
TokenClassification.Selection, "Get-Many1 ",
|
||||
TokenClassification.None,
|
||||
"Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "12", NextLine,
|
||||
TokenClassification.None, "Get-Many0 Get-Many3 Get-Many6 Get-Many9 ",
|
||||
TokenClassification.Selection, "Get-Many12 ", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "9", NextLine,
|
||||
TokenClassification.None, "Get-Many0 Get-Many3 Get-Many6 ",
|
||||
TokenClassification.Selection, "Get-Many9 ",
|
||||
TokenClassification.None, "Get-Many12", NextLine,
|
||||
"Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "6", NextLine,
|
||||
TokenClassification.None, "Get-Many0 Get-Many3 ",
|
||||
TokenClassification.Selection, "Get-Many6 ",
|
||||
TokenClassification.None, "Get-Many9 Get-Many12", NextLine,
|
||||
"Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14")),
|
||||
_.LeftArrow, _.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "0", NextLine,
|
||||
TokenClassification.Selection, "Get-Many0 ",
|
||||
TokenClassification.None,
|
||||
"Get-Many3 Get-Many6 Get-Many9 Get-Many12", NextLine,
|
||||
"Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "14", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Many0 Get-Many3 Get-Many6 Get-Many9 Get-Many12", NextLine,
|
||||
"Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 ",
|
||||
TokenClassification.Selection, "Get-Many14 ", NextLine)),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Many",
|
||||
TokenClassification.Selection, "0", NextLine,
|
||||
TokenClassification.Selection, "Get-Many0 ",
|
||||
TokenClassification.None,
|
||||
"Get-Many3 Get-Many6 Get-Many9 Get-Many12", NextLine,
|
||||
"Get-Many1 Get-Many4 Get-Many7 Get-Many10 Get-Many13", NextLine,
|
||||
"Get-Many2 Get-Many5 Get-Many8 Get-Many11 Get-Many14")),
|
||||
_.Enter,
|
||||
_.Enter
|
||||
));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void MenuCompletions_Navigation2()
|
||||
{
|
||||
// Test 'RightArrow' with the following menu:
|
||||
// Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12
|
||||
// Get-Less1 Get-Less4 Get-Less7 Get-Less10
|
||||
// Get-Less2 Get-Less5 Get-Less8 Get-Less11
|
||||
|
||||
TestSetup(KeyMode.Cmd, new KeyHandler("Ctrl+Spacebar", PSConsoleReadLine.MenuComplete));
|
||||
|
||||
_console.Clear();
|
||||
Test("Get-Less0", Keys(
|
||||
"Get-Less", _.Ctrl_Spacebar,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "0", NextLine,
|
||||
TokenClassification.Selection, "Get-Less0 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.RightArrow, _.RightArrow, _.RightArrow, _.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "12", NextLine,
|
||||
TokenClassification.None, "Get-Less0 Get-Less3 Get-Less6 Get-Less9 ",
|
||||
TokenClassification.Selection, "Get-Less12 ", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "1", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
TokenClassification.Selection, "Get-Less1 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.RightArrow, _.RightArrow, _.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "10", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 ",
|
||||
TokenClassification.Selection, "Get-Less10 ", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "2", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
TokenClassification.Selection, "Get-Less2 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.RightArrow, _.RightArrow, _.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "11", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 ",
|
||||
TokenClassification.Selection, "Get-Less11 ")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "0", NextLine,
|
||||
TokenClassification.Selection, "Get-Less0 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.Enter,
|
||||
_.Enter
|
||||
));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void MenuCompletions_Navigation3()
|
||||
{
|
||||
// Test 'LeftArrow' with the following menu:
|
||||
// Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12
|
||||
// Get-Less1 Get-Less4 Get-Less7 Get-Less10
|
||||
// Get-Less2 Get-Less5 Get-Less8 Get-Less11
|
||||
|
||||
TestSetup(KeyMode.Cmd, new KeyHandler("Ctrl+Spacebar", PSConsoleReadLine.MenuComplete));
|
||||
|
||||
_console.Clear();
|
||||
Test("Get-Less6", Keys(
|
||||
"Get-Less", _.Ctrl_Spacebar,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "0", NextLine,
|
||||
TokenClassification.Selection, "Get-Less0 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "11", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 ",
|
||||
TokenClassification.Selection, "Get-Less11 ")),
|
||||
_.LeftArrow, _.LeftArrow, _.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "2", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
TokenClassification.Selection, "Get-Less2 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "10", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 ",
|
||||
TokenClassification.Selection, "Get-Less10 ", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.LeftArrow, _.LeftArrow, _.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "1", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
TokenClassification.Selection, "Get-Less1 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "12", NextLine,
|
||||
TokenClassification.None, "Get-Less0 Get-Less3 Get-Less6 Get-Less9 ",
|
||||
TokenClassification.Selection, "Get-Less12 ", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.LeftArrow, _.LeftArrow,
|
||||
_.Enter,
|
||||
_.Enter
|
||||
));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void MenuCompletions_Navigation4()
|
||||
{
|
||||
// Test 'UpArrow' and 'DownArrow' with the following menu:
|
||||
// Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12
|
||||
// Get-Less1 Get-Less4 Get-Less7 Get-Less10
|
||||
// Get-Less2 Get-Less5 Get-Less8 Get-Less11
|
||||
|
||||
TestSetup(KeyMode.Cmd, new KeyHandler("Ctrl+Spacebar", PSConsoleReadLine.MenuComplete));
|
||||
|
||||
_console.Clear();
|
||||
Test("Get-Less0", Keys(
|
||||
"Get-Less", _.Ctrl_Spacebar,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "0", NextLine,
|
||||
TokenClassification.Selection, "Get-Less0 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.DownArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "1", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
TokenClassification.Selection, "Get-Less1 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.DownArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "2", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
TokenClassification.Selection, "Get-Less2 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.DownArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "3", NextLine,
|
||||
TokenClassification.None, "Get-Less0 ",
|
||||
TokenClassification.Selection, "Get-Less3 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.UpArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "2", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
TokenClassification.Selection, "Get-Less2 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.UpArrow, _.UpArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "0", NextLine,
|
||||
TokenClassification.Selection, "Get-Less0 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.UpArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "12", NextLine,
|
||||
TokenClassification.None, "Get-Less0 Get-Less3 Get-Less6 Get-Less9 ",
|
||||
TokenClassification.Selection, "Get-Less12 ", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.UpArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "11", NextLine,
|
||||
TokenClassification.None,
|
||||
"Get-Less0 Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 ",
|
||||
TokenClassification.Selection, "Get-Less11 ")),
|
||||
_.DownArrow, _.DownArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Less",
|
||||
TokenClassification.Selection, "0", NextLine,
|
||||
TokenClassification.Selection, "Get-Less0 ",
|
||||
TokenClassification.None,
|
||||
"Get-Less3 Get-Less6 Get-Less9 Get-Less12", NextLine,
|
||||
"Get-Less1 Get-Less4 Get-Less7 Get-Less10", NextLine,
|
||||
"Get-Less2 Get-Less5 Get-Less8 Get-Less11")),
|
||||
_.Enter,
|
||||
_.Enter
|
||||
));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void MenuCompletions_Navigation5()
|
||||
{
|
||||
// Test 'UpArrow', 'DownArrow', 'LeftArrow', and 'RightArrow' with the following menu:
|
||||
// Get-MockDynamicParameters Get-Module
|
||||
|
||||
TestSetup(KeyMode.Cmd, new KeyHandler("Ctrl+Spacebar", PSConsoleReadLine.MenuComplete));
|
||||
|
||||
_console.Clear();
|
||||
Test("Get-MockDynamicParameters", Keys(
|
||||
"Get-Mo", _.Ctrl_Spacebar,
|
||||
CheckThat(() => AssertScreenIs(2,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "ckDynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-MockDynamicParameters ",
|
||||
TokenClassification.None, "Get-Module")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "dule", NextLine,
|
||||
TokenClassification.None, "Get-MockDynamicParameters ",
|
||||
TokenClassification.Selection, "Get-Module ")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(2,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "ckDynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-MockDynamicParameters ",
|
||||
TokenClassification.None, "Get-Module")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "dule", NextLine,
|
||||
TokenClassification.None, "Get-MockDynamicParameters ",
|
||||
TokenClassification.Selection, "Get-Module ")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(2,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "ckDynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-MockDynamicParameters ",
|
||||
TokenClassification.None, "Get-Module")),
|
||||
_.UpArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "dule", NextLine,
|
||||
TokenClassification.None, "Get-MockDynamicParameters ",
|
||||
TokenClassification.Selection, "Get-Module ")),
|
||||
_.UpArrow,
|
||||
CheckThat(() => AssertScreenIs(2,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "ckDynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-MockDynamicParameters ",
|
||||
TokenClassification.None, "Get-Module")),
|
||||
_.DownArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "dule", NextLine,
|
||||
TokenClassification.None, "Get-MockDynamicParameters ",
|
||||
TokenClassification.Selection, "Get-Module ")),
|
||||
_.DownArrow,
|
||||
CheckThat(() => AssertScreenIs(2,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "ckDynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-MockDynamicParameters ",
|
||||
TokenClassification.None, "Get-Module")),
|
||||
_.Enter,
|
||||
_.Enter
|
||||
));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void MenuCompletions_Navigation6()
|
||||
{
|
||||
// Test 'UpArrow', 'DownArrow', 'LeftArrow', and 'RightArrow' with the following menu:
|
||||
// Get-NewDynamicParameters Get-NewStyle
|
||||
// Get-NewIdea
|
||||
|
||||
TestSetup(KeyMode.Cmd, new KeyHandler("Ctrl+Spacebar", PSConsoleReadLine.MenuComplete));
|
||||
|
||||
_console.Clear();
|
||||
Test("Get-NewDynamicParameters", Keys(
|
||||
"Get-New", _.Ctrl_Spacebar,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "DynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-NewDynamicParameters ",
|
||||
TokenClassification.None, "Get-NewStyle", NextLine,
|
||||
TokenClassification.None, "Get-NewIdea")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "Style", NextLine,
|
||||
TokenClassification.None, "Get-NewDynamicParameters ",
|
||||
TokenClassification.Selection, "Get-NewStyle ", NextLine,
|
||||
TokenClassification.None, "Get-NewIdea")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "Idea", NextLine,
|
||||
TokenClassification.None, "Get-NewDynamicParameters Get-NewStyle", NextLine,
|
||||
TokenClassification.Selection, "Get-NewIdea ")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "DynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-NewDynamicParameters ",
|
||||
TokenClassification.None, "Get-NewStyle", NextLine,
|
||||
TokenClassification.None, "Get-NewIdea")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "Idea", NextLine,
|
||||
TokenClassification.None, "Get-NewDynamicParameters Get-NewStyle", NextLine,
|
||||
TokenClassification.Selection, "Get-NewIdea ")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "Style", NextLine,
|
||||
TokenClassification.None, "Get-NewDynamicParameters ",
|
||||
TokenClassification.Selection, "Get-NewStyle ", NextLine,
|
||||
TokenClassification.None, "Get-NewIdea")),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "DynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-NewDynamicParameters ",
|
||||
TokenClassification.None, "Get-NewStyle", NextLine,
|
||||
TokenClassification.None, "Get-NewIdea")),
|
||||
_.DownArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "Idea", NextLine,
|
||||
TokenClassification.None, "Get-NewDynamicParameters Get-NewStyle", NextLine,
|
||||
TokenClassification.Selection, "Get-NewIdea ")),
|
||||
_.DownArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "Style", NextLine,
|
||||
TokenClassification.None, "Get-NewDynamicParameters ",
|
||||
TokenClassification.Selection, "Get-NewStyle ", NextLine,
|
||||
TokenClassification.None, "Get-NewIdea")),
|
||||
_.DownArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "DynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-NewDynamicParameters ",
|
||||
TokenClassification.None, "Get-NewStyle", NextLine,
|
||||
TokenClassification.None, "Get-NewIdea")),
|
||||
_.UpArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "Style", NextLine,
|
||||
TokenClassification.None, "Get-NewDynamicParameters ",
|
||||
TokenClassification.Selection, "Get-NewStyle ", NextLine,
|
||||
TokenClassification.None, "Get-NewIdea")),
|
||||
_.UpArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "Idea", NextLine,
|
||||
TokenClassification.None, "Get-NewDynamicParameters Get-NewStyle", NextLine,
|
||||
TokenClassification.Selection, "Get-NewIdea ")),
|
||||
_.UpArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-New",
|
||||
TokenClassification.Selection, "DynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-NewDynamicParameters ",
|
||||
TokenClassification.None, "Get-NewStyle", NextLine,
|
||||
TokenClassification.None, "Get-NewIdea")),
|
||||
_.Enter,
|
||||
_.Enter
|
||||
));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void MenuCompletions_ClearProperly()
|
||||
{
|
||||
TestSetup(KeyMode.Cmd, new KeyHandler("Ctrl+Spacebar", PSConsoleReadLine.MenuComplete));
|
||||
|
||||
_console.Clear();
|
||||
int width = _console.BufferWidth;
|
||||
string placeholderCommand = new string('A', width - 12); // 12 = "Get-Module".Length + 2
|
||||
string emptyLine = new string(' ', width);
|
||||
|
||||
Test($"{placeholderCommand};Get-Module", Keys(
|
||||
placeholderCommand, ';',
|
||||
"Get-Mo", _.Ctrl_Spacebar,
|
||||
// At this point, the editing line buffer takes 2 physical lines.
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, placeholderCommand,
|
||||
TokenClassification.None, ';',
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "ckDynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-MockDynamicParameters ",
|
||||
TokenClassification.None, "Get-Module ", NextLine,
|
||||
TokenClassification.None, emptyLine)),
|
||||
_.RightArrow,
|
||||
// Navigating to the next item will cause the editing line to fit in
|
||||
// one physical line, so the new menu is moved up and lines from the
|
||||
// previous menu need to be properly cleared.
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, placeholderCommand,
|
||||
TokenClassification.None, ';',
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "dule", NextLine,
|
||||
TokenClassification.None, "Get-MockDynamicParameters ",
|
||||
TokenClassification.Selection, "Get-Module ", NextLine,
|
||||
TokenClassification.None, emptyLine)),
|
||||
_.LeftArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, placeholderCommand,
|
||||
TokenClassification.None, ';',
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "ckDynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-MockDynamicParameters ",
|
||||
TokenClassification.None, "Get-Module ", NextLine,
|
||||
TokenClassification.None, emptyLine)),
|
||||
_.DownArrow,
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, placeholderCommand,
|
||||
TokenClassification.None, ';',
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "dule", NextLine,
|
||||
TokenClassification.None, "Get-MockDynamicParameters ",
|
||||
TokenClassification.Selection, "Get-Module ", NextLine,
|
||||
TokenClassification.None, emptyLine)),
|
||||
_.Enter,
|
||||
_.Enter
|
||||
));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void MenuCompletions_WorkWithListView()
|
||||
{
|
||||
TestSetup(KeyMode.Cmd, new KeyHandler("Ctrl+Spacebar", PSConsoleReadLine.MenuComplete));
|
||||
|
||||
var (listWidth, windowWidth) = CheckWindowSize();
|
||||
var emphasisColors = Tuple.Create(PSConsoleReadLineOptions.DefaultEmphasisColor, _console.BackgroundColor);
|
||||
string emptyLine = new string(' ', windowWidth);
|
||||
using var disp = SetPrediction(PredictionSource.History, PredictionViewStyle.ListView);
|
||||
|
||||
_console.Clear();
|
||||
SetHistory("Get-Mocha -AddMilk -AddSugur -ExtraCup", "Get-MoreBook -Kind Fiction -FlatCover");
|
||||
|
||||
Test("Get-Module", Keys(
|
||||
"Get-Mo",
|
||||
CheckThat(() => AssertScreenIs(3,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
NextLine,
|
||||
TokenClassification.ListPrediction, '>',
|
||||
TokenClassification.None, ' ',
|
||||
emphasisColors, "Get-Mo",
|
||||
TokenClassification.None, "reBook -Kind Fiction -FlatCover",
|
||||
TokenClassification.None, new string(' ', listWidth - 48), // 48 is the length of '> Get-MoreBook -Kind Fiction -FlatCover' plus '[History]'.
|
||||
TokenClassification.None, '[',
|
||||
TokenClassification.ListPrediction, "History",
|
||||
TokenClassification.None, ']',
|
||||
NextLine,
|
||||
TokenClassification.ListPrediction, '>',
|
||||
TokenClassification.None, ' ',
|
||||
emphasisColors, "Get-Mo",
|
||||
TokenClassification.None, "cha -AddMilk -AddSugur -ExtraCup",
|
||||
TokenClassification.None, new string(' ', listWidth - 49), // 49 is the length of '> Get-Mocha -AddMilk -AddSugur -ExtraCup' plus '[History]'.
|
||||
TokenClassification.None, '[',
|
||||
TokenClassification.ListPrediction, "History",
|
||||
TokenClassification.None, ']')),
|
||||
_.Ctrl_Spacebar,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "ckDynamicParameters", NextLine,
|
||||
TokenClassification.Selection, "Get-MockDynamicParameters ",
|
||||
TokenClassification.None, "Get-Module", NextLine,
|
||||
TokenClassification.None, emptyLine,
|
||||
TokenClassification.None, emptyLine)),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(4,
|
||||
TokenClassification.Command, "Get-Mo",
|
||||
TokenClassification.Selection, "dule", NextLine,
|
||||
TokenClassification.None, "Get-MockDynamicParameters ",
|
||||
TokenClassification.Selection, "Get-Module ", NextLine,
|
||||
TokenClassification.None, emptyLine,
|
||||
TokenClassification.None, emptyLine)),
|
||||
_.Enter,
|
||||
_.Enter
|
||||
));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void ShowTooltips()
|
||||
{
|
||||
@@ -249,6 +922,21 @@ namespace Test
|
||||
completions.Add(new CompletionResult("Get-Many" + i));
|
||||
}
|
||||
break;
|
||||
case "Get-Less":
|
||||
replacementIndex = 0;
|
||||
replacementLength = 8;
|
||||
for (int i = 0; i < 13; i++)
|
||||
{
|
||||
completions.Add(new CompletionResult("Get-Less" + i));
|
||||
}
|
||||
break;
|
||||
case "Get-New":
|
||||
replacementIndex = 0;
|
||||
replacementLength = 7;
|
||||
completions.Add(new CompletionResult("Get-NewDynamicParameters"));
|
||||
completions.Add(new CompletionResult("Get-NewIdea"));
|
||||
completions.Add(new CompletionResult("Get-NewStyle"));
|
||||
break;
|
||||
case "Get-Tooltips":
|
||||
replacementIndex = 0;
|
||||
replacementLength = 12;
|
||||
@@ -290,6 +978,16 @@ namespace Test
|
||||
break;
|
||||
case "none":
|
||||
break;
|
||||
|
||||
default:
|
||||
if (input.EndsWith("Get-Mo", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
replacementIndex = input.IndexOf("Get-Mo", StringComparison.OrdinalIgnoreCase);
|
||||
replacementLength = 6;
|
||||
completions.Add(new CompletionResult("Get-MockDynamicParameters"));
|
||||
completions.Add(new CompletionResult("Get-Module"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return (CommandCompletion)ctor.Invoke(
|
||||
|
||||
@@ -182,6 +182,11 @@ namespace Test
|
||||
|
||||
public void SetCursorPosition(int left, int top)
|
||||
{
|
||||
if (left != CursorLeft || top != CursorTop)
|
||||
{
|
||||
_ignoreNextNewline = false;
|
||||
}
|
||||
|
||||
CursorLeft = left;
|
||||
CursorTop = top;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user