Skip to content

Commit 0824ad1

Browse files
authored
Make HistorySearchBackward and HistorySearchForward able to navigate the list view (#3144)
1 parent 17fe4a5 commit 0824ad1

File tree

2 files changed

+212
-2
lines changed

2 files changed

+212
-2
lines changed

PSReadLine/History.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,11 @@ public static void HistorySearchBackward(ConsoleKeyInfo? key = null, object arg
958958
numericArg = -numericArg;
959959
}
960960

961+
if (UpdateListSelection(numericArg))
962+
{
963+
return;
964+
}
965+
961966
_singleton.SaveCurrentLine();
962967
_singleton.HistorySearch(numericArg);
963968
}
@@ -969,6 +974,10 @@ public static void HistorySearchBackward(ConsoleKeyInfo? key = null, object arg
969974
public static void HistorySearchForward(ConsoleKeyInfo? key = null, object arg = null)
970975
{
971976
TryGetArgAsInt(arg, out var numericArg, +1);
977+
if (UpdateListSelection(numericArg))
978+
{
979+
return;
980+
}
972981

973982
_singleton.SaveCurrentLine();
974983
_singleton.HistorySearch(numericArg);

test/ListPredictionTest.cs

Lines changed: 203 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ private void AssertDisplayedSuggestions(int count, Guid predictorId, uint sessio
4747
}
4848

4949
[SkippableFact]
50-
public void List_RenderSuggestion_NoMatching()
50+
public void List_RenderSuggestion_NoMatching_DefaultUpArrowDownArrow()
5151
{
5252
TestSetup(KeyMode.Cmd);
5353
using var disp = SetPrediction(PredictionSource.History, PredictionViewStyle.ListView);
@@ -64,6 +64,25 @@ public void List_RenderSuggestion_NoMatching()
6464
));
6565
}
6666

67+
[SkippableFact]
68+
public void List_RenderSuggestion_NoMatching_HistorySearchBackwardForward()
69+
{
70+
TestSetup(KeyMode.Cmd,
71+
new KeyHandler("Ctrl+p", PSConsoleReadLine.HistorySearchBackward),
72+
new KeyHandler("Ctrl+l", PSConsoleReadLine.HistorySearchForward));
73+
using var disp = SetPrediction(PredictionSource.History, PredictionViewStyle.ListView);
74+
75+
// No matching history entry
76+
SetHistory("echo -bar", "eca -zoo");
77+
Test(string.Empty, Keys(
78+
_.Ctrl_p, CheckThat(() => AssertLineIs("eca -zoo")),
79+
_.Ctrl_p, CheckThat(() => AssertLineIs("echo -bar")),
80+
_.Ctrl_l, _.Ctrl_l,
81+
CheckThat(() => AssertLineIs(string.Empty)),
82+
CheckThat(() => AssertCursorLeftIs(0))
83+
));
84+
}
85+
6786
[SkippableFact]
6887
public void List_RenderSuggestion_ListUpdatesWhileTyping()
6988
{
@@ -138,7 +157,7 @@ public void List_RenderSuggestion_ListUpdatesWhileTyping()
138157
}
139158

140159
[SkippableFact]
141-
public void List_RenderSuggestion_NavigateInList()
160+
public void List_RenderSuggestion_NavigateInList_DefaultUpArrowDownArrow()
142161
{
143162
TestSetup(KeyMode.Cmd);
144163
int listWidth = CheckWindowSize();
@@ -317,6 +336,188 @@ public void List_RenderSuggestion_NavigateInList()
317336
));
318337
}
319338

339+
[SkippableFact]
340+
public void List_RenderSuggestion_NavigateInList_HistorySearchBackwardForward()
341+
{
342+
TestSetup(KeyMode.Cmd,
343+
new KeyHandler("Ctrl+p", PSConsoleReadLine.HistorySearchBackward),
344+
new KeyHandler("Ctrl+l", PSConsoleReadLine.HistorySearchForward));
345+
int listWidth = CheckWindowSize();
346+
var emphasisColors = Tuple.Create(PSConsoleReadLineOptions.DefaultEmphasisColor, _console.BackgroundColor);
347+
using var disp = SetPrediction(PredictionSource.History, PredictionViewStyle.ListView);
348+
349+
// Navigate up and down in the list
350+
SetHistory("echo -bar", "eca -zoo");
351+
Test("e", Keys(
352+
'e', CheckThat(() => AssertScreenIs(3,
353+
TokenClassification.Command, 'e',
354+
NextLine,
355+
TokenClassification.ListPrediction, '>',
356+
TokenClassification.None, ' ',
357+
emphasisColors, 'e',
358+
TokenClassification.None, "ca -zoo",
359+
TokenClassification.None, new string(' ', listWidth - 19), // 19 is the length of '> eca -zoo' plus '[History]'.
360+
TokenClassification.None, '[',
361+
TokenClassification.ListPrediction, "History",
362+
TokenClassification.None, ']',
363+
NextLine,
364+
TokenClassification.ListPrediction, '>',
365+
TokenClassification.None, ' ',
366+
emphasisColors, 'e',
367+
TokenClassification.None, "cho -bar",
368+
TokenClassification.None, new string(' ', listWidth - 20), // 20 is the length of '> echo -bar' plus '[History]'.
369+
TokenClassification.None, '[',
370+
TokenClassification.ListPrediction, "History",
371+
TokenClassification.None, ']'
372+
)),
373+
_.Ctrl_l,
374+
CheckThat(() => AssertScreenIs(3,
375+
TokenClassification.Command, "eca",
376+
TokenClassification.None, ' ',
377+
TokenClassification.Parameter, "-zoo",
378+
NextLine,
379+
TokenClassification.ListPrediction, '>',
380+
TokenClassification.ListPredictionSelected, ' ',
381+
emphasisColors, 'e',
382+
TokenClassification.ListPredictionSelected, "ca -zoo",
383+
TokenClassification.ListPredictionSelected, new string(' ', listWidth - 19), // 19 is the length of '> eca -zoo' plus '[History]'.
384+
TokenClassification.ListPredictionSelected, '[',
385+
TokenClassification.ListPrediction, "History",
386+
TokenClassification.ListPredictionSelected, ']',
387+
NextLine,
388+
TokenClassification.ListPrediction, '>',
389+
TokenClassification.None, ' ',
390+
emphasisColors, 'e',
391+
TokenClassification.None, "cho -bar",
392+
TokenClassification.None, new string(' ', listWidth - 20), // 20 is the length of '> echo -bar' plus '[History]'.
393+
TokenClassification.None, '[',
394+
TokenClassification.ListPrediction, "History",
395+
TokenClassification.None, ']'
396+
)),
397+
_.Ctrl_l,
398+
CheckThat(() => AssertScreenIs(3,
399+
TokenClassification.Command, "echo",
400+
TokenClassification.None, ' ',
401+
TokenClassification.Parameter, "-bar",
402+
NextLine,
403+
TokenClassification.ListPrediction, '>',
404+
TokenClassification.None, ' ',
405+
emphasisColors, 'e',
406+
TokenClassification.None, "ca -zoo",
407+
TokenClassification.None, new string(' ', listWidth - 19), // 19 is the length of '> eca -zoo' plus '[History]'.
408+
TokenClassification.None, '[',
409+
TokenClassification.ListPrediction, "History",
410+
TokenClassification.None, ']',
411+
NextLine,
412+
TokenClassification.ListPrediction, '>',
413+
TokenClassification.ListPredictionSelected, ' ',
414+
emphasisColors, 'e',
415+
TokenClassification.ListPredictionSelected, "cho -bar",
416+
TokenClassification.ListPredictionSelected, new string(' ', listWidth - 20), // 20 is the length of '> echo -bar' plus '[History]'.
417+
TokenClassification.ListPredictionSelected, '[',
418+
TokenClassification.ListPrediction, "History",
419+
TokenClassification.ListPredictionSelected, ']'
420+
)),
421+
_.Ctrl_l,
422+
CheckThat(() => AssertScreenIs(3,
423+
TokenClassification.Command, 'e',
424+
NextLine,
425+
TokenClassification.ListPrediction, '>',
426+
TokenClassification.None, ' ',
427+
emphasisColors, 'e',
428+
TokenClassification.None, "ca -zoo",
429+
TokenClassification.None, new string(' ', listWidth - 19), // 19 is the length of '> eca -zoo' plus '[History]'.
430+
TokenClassification.None, '[',
431+
TokenClassification.ListPrediction, "History",
432+
TokenClassification.None, ']',
433+
NextLine,
434+
TokenClassification.ListPrediction, '>',
435+
TokenClassification.None, ' ',
436+
emphasisColors, 'e',
437+
TokenClassification.None, "cho -bar",
438+
TokenClassification.None, new string(' ', listWidth - 20), // 20 is the length of '> echo -bar' plus '[History]'.
439+
TokenClassification.None, '[',
440+
TokenClassification.ListPrediction, "History",
441+
TokenClassification.None, ']'
442+
)),
443+
_.Ctrl_p,
444+
CheckThat(() => AssertScreenIs(3,
445+
TokenClassification.Command, "echo",
446+
TokenClassification.None, ' ',
447+
TokenClassification.Parameter, "-bar",
448+
NextLine,
449+
TokenClassification.ListPrediction, '>',
450+
TokenClassification.None, ' ',
451+
emphasisColors, 'e',
452+
TokenClassification.None, "ca -zoo",
453+
TokenClassification.None, new string(' ', listWidth - 19), // 19 is the length of '> eca -zoo' plus '[History]'.
454+
TokenClassification.None, '[',
455+
TokenClassification.ListPrediction, "History",
456+
TokenClassification.None, ']',
457+
NextLine,
458+
TokenClassification.ListPrediction, '>',
459+
TokenClassification.ListPredictionSelected, ' ',
460+
emphasisColors, 'e',
461+
TokenClassification.ListPredictionSelected, "cho -bar",
462+
TokenClassification.ListPredictionSelected, new string(' ', listWidth - 20), // 20 is the length of '> echo -bar' plus '[History]'.
463+
TokenClassification.ListPredictionSelected, '[',
464+
TokenClassification.ListPrediction, "History",
465+
TokenClassification.ListPredictionSelected, ']'
466+
)),
467+
_.Ctrl_p,
468+
CheckThat(() => AssertScreenIs(3,
469+
TokenClassification.Command, "eca",
470+
TokenClassification.None, ' ',
471+
TokenClassification.Parameter, "-zoo",
472+
NextLine,
473+
TokenClassification.ListPrediction, '>',
474+
TokenClassification.ListPredictionSelected, ' ',
475+
emphasisColors, 'e',
476+
TokenClassification.ListPredictionSelected, "ca -zoo",
477+
TokenClassification.ListPredictionSelected, new string(' ', listWidth - 19), // 19 is the length of '> eca -zoo' plus '[History]'.
478+
TokenClassification.ListPredictionSelected, '[',
479+
TokenClassification.ListPrediction, "History",
480+
TokenClassification.ListPredictionSelected, ']',
481+
NextLine,
482+
TokenClassification.ListPrediction, '>',
483+
TokenClassification.None, ' ',
484+
emphasisColors, 'e',
485+
TokenClassification.None, "cho -bar",
486+
TokenClassification.None, new string(' ', listWidth - 20), // 20 is the length of '> echo -bar' plus '[History]'.
487+
TokenClassification.None, '[',
488+
TokenClassification.ListPrediction, "History",
489+
TokenClassification.None, ']'
490+
)),
491+
_.Ctrl_p,
492+
CheckThat(() => AssertScreenIs(3,
493+
TokenClassification.Command, 'e',
494+
NextLine,
495+
TokenClassification.ListPrediction, '>',
496+
TokenClassification.None, ' ',
497+
emphasisColors, 'e',
498+
TokenClassification.None, "ca -zoo",
499+
TokenClassification.None, new string(' ', listWidth - 19), // 19 is the length of '> eca -zoo' plus '[History]'.
500+
TokenClassification.None, '[',
501+
TokenClassification.ListPrediction, "History",
502+
TokenClassification.None, ']',
503+
NextLine,
504+
TokenClassification.ListPrediction, '>',
505+
TokenClassification.None, ' ',
506+
emphasisColors, 'e',
507+
TokenClassification.None, "cho -bar",
508+
TokenClassification.None, new string(' ', listWidth - 20), // 20 is the length of '> echo -bar' plus '[History]'.
509+
TokenClassification.None, '[',
510+
TokenClassification.ListPrediction, "History",
511+
TokenClassification.None, ']'
512+
)),
513+
// Once accepted, the list should be cleared.
514+
_.Enter, CheckThat(() => AssertScreenIs(2,
515+
TokenClassification.Command, "e",
516+
NextLine,
517+
NextLine))
518+
));
519+
}
520+
320521
[SkippableFact]
321522
public void List_RenderSuggestion_Escape()
322523
{

0 commit comments

Comments
 (0)