Skip to content

Commit acb8ccb

Browse files
authored
Make Ctrl+r in Vi edit mode same as Emacs edit mode (#3148)
1 parent 0824ad1 commit acb8ccb

File tree

2 files changed

+110
-24
lines changed

2 files changed

+110
-24
lines changed

PSReadLine/KeyBindings.vi.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,9 @@ private void SetDefaultViBindings()
8686
{ Keys.F3, MakeKeyHandler(CharacterSearch, "CharacterSearch") },
8787
{ Keys.ShiftF3, MakeKeyHandler(CharacterSearchBackward,"CharacterSearchBackward") },
8888
{ Keys.CtrlAltQuestion, MakeKeyHandler(ShowKeyBindings, "ShowKeyBindings") },
89-
{ Keys.CtrlR, MakeKeyHandler(ViSearchHistoryBackward,"ViSearchHistoryBackward") },
90-
{ Keys.CtrlS, MakeKeyHandler(SearchForward, "SearchForward") },
89+
{ Keys.CtrlR, MakeKeyHandler(ReverseSearchHistory, "ReverseSearchHistory") },
90+
{ Keys.CtrlS, MakeKeyHandler(ForwardSearchHistory, "ForwardSearchHistory") },
91+
{ Keys.CtrlG, MakeKeyHandler(Abort, "Abort") },
9192
{ Keys.AltH, MakeKeyHandler(ShowParameterHelp, "ShowParameterHelp") },
9293
{ Keys.F1, MakeKeyHandler(ShowCommandHelp, "ShowCommandHelp") },
9394
};
@@ -201,10 +202,11 @@ private void SetDefaultViBindings()
201202
{ Keys.Uphat, MakeKeyHandler(GotoFirstNonBlankOfLine, "GotoFirstNonBlankOfLine") },
202203
{ Keys.Underbar, MakeKeyHandler(GotoFirstNonBlankOfLine, "GotoFirstNonBlankOfLine") },
203204
{ Keys.Tilde, MakeKeyHandler(InvertCase, "InvertCase") },
204-
{ Keys.Slash, MakeKeyHandler(ViSearchHistoryBackward, "ViSearchHistoryBackward") },
205-
{ Keys.CtrlR, MakeKeyHandler(ViSearchHistoryBackward, "ViSearchHistoryBackward") },
205+
{ Keys.Slash, MakeKeyHandler(ViSearchHistoryBackward, "ViSearchHistoryBackward") },
206206
{ Keys.Question, MakeKeyHandler(SearchForward, "SearchForward") },
207-
{ Keys.CtrlS, MakeKeyHandler(SearchForward, "SearchForward") },
207+
{ Keys.CtrlR, MakeKeyHandler(ReverseSearchHistory, "ReverseSearchHistory") },
208+
{ Keys.CtrlS, MakeKeyHandler(ForwardSearchHistory, "ForwardSearchHistory") },
209+
{ Keys.CtrlG, MakeKeyHandler(Abort, "Abort") },
208210
{ Keys.Plus, MakeKeyHandler(NextHistory, "NextHistory") },
209211
{ Keys.Minus, MakeKeyHandler(PreviousHistory, "PreviousHistory") },
210212
{ Keys.Period, MakeKeyHandler(RepeatLastCommand, "RepeatLastCommand") },

test/HistoryTest.VI.cs

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Microsoft.PowerShell;
1+
using System;
2+
using Microsoft.PowerShell;
23
using Xunit;
34

45
namespace Test
@@ -56,31 +57,114 @@ public void ViSearchHistory()
5657

5758
// Clear history in case the above added some history (but it shouldn't)
5859
SetHistory();
59-
Test( " ", Keys( ' ', _.UpArrow, _.DownArrow ) );
60-
61-
SetHistory( "dosomething", "this way", "that way", "anyway", "no way", "yah way" );
60+
Test(" ", Keys(' ', _.UpArrow, _.DownArrow));
6261

63-
Test( "dosomething", Keys(
64-
_.Escape, _.Slash, "some", _.Enter, CheckThat( () => AssertLineIs( "dosomething" ) ),
65-
_.Question, "yah", _.Enter, CheckThat( () => AssertLineIs( "yah way" ) ),
66-
_.Slash, "some", _.Enter, 'h' // need 'h' here to avoid bogus failure
67-
) );
62+
var emphasisColors = Tuple.Create(PSConsoleReadLineOptions.DefaultEmphasisColor, _console.BackgroundColor);
63+
var statusColors = Tuple.Create(_console.ForegroundColor, _console.BackgroundColor);
6864

6965
SetHistory("dosomething", "this way", "that way", "anyway", "no way", "yah way");
7066

7167
Test("dosomething", Keys(
72-
_.Escape, _.Ctrl_r, "some", _.Enter, CheckThat(() => AssertLineIs("dosomething")),
73-
_.Ctrl_s, "yah", _.Enter, CheckThat(() => AssertLineIs("yah way")),
74-
_.Ctrl_r, "some", _.Enter, 'h' // need 'h' here to avoid bogus failure
68+
_.Escape, _.Slash, "some", _.Enter, CheckThat(() => AssertLineIs("dosomething")),
69+
_.Question, "yah", _.Enter, CheckThat(() => AssertLineIs("yah way")),
70+
_.Slash, "some", _.Enter, 'h' // need 'h' here to avoid bogus failure
7571
));
7672

77-
SetHistory("dosomething", "this way", "that way", "anyway", "no way", "yah way");
78-
79-
Test("dosomething", Keys(
80-
_.Ctrl_r, "some", _.Enter, CheckThat(() => AssertLineIs("dosomething")),
81-
_.Ctrl_s, "yah", _.Enter, CheckThat(() => AssertLineIs("yah way")),
82-
_.Ctrl_r, "some", _.Enter, _.Escape // new esc here to avoid bogus failure
83-
));
73+
SetHistory("someway", "noway", "yahway");
74+
75+
Test("yahway", Keys(
76+
// Change to Command mode.
77+
_.Escape,
78+
_.Ctrl_r, "way",
79+
CheckThat(() => AssertScreenIs(2,
80+
TokenClassification.Command, "yah",
81+
emphasisColors, "way",
82+
NextLine,
83+
statusColors, "bck-i-search: way_")),
84+
_.Ctrl_r,
85+
CheckThat(() => AssertScreenIs(2,
86+
TokenClassification.Command, "no",
87+
emphasisColors, "way",
88+
NextLine,
89+
statusColors, "bck-i-search: way_")),
90+
_.Ctrl_r,
91+
CheckThat(() => AssertScreenIs(2,
92+
TokenClassification.Command, "some",
93+
emphasisColors, "way",
94+
NextLine,
95+
statusColors, "bck-i-search: way_")),
96+
_.Ctrl_s,
97+
CheckThat(() => AssertScreenIs(2,
98+
TokenClassification.Command, "no",
99+
emphasisColors, "way",
100+
NextLine,
101+
statusColors, "fwd-i-search: way_")),
102+
_.Ctrl_s,
103+
CheckThat(() => AssertScreenIs(2,
104+
TokenClassification.Command, "yah",
105+
emphasisColors, "way",
106+
NextLine,
107+
statusColors, "fwd-i-search: way_")),
108+
_.Ctrl_s,
109+
CheckThat(() => AssertScreenIs(2,
110+
TokenClassification.Command, "yahway",
111+
NextLine,
112+
statusColors, "failed-fwd-i-search: way_")),
113+
114+
// Abort the history search.
115+
_.Ctrl_g, CheckThat(() => AssertLineIs(string.Empty)),
116+
// Search again and escape from the search.
117+
_.Ctrl_r, "yah",
118+
_.Escape, CheckThat(() => AssertScreenIs(1, TokenClassification.Command, "yahway")),
119+
// We should not be able to edit the line, because we are in Command mode.
120+
"nnn"));
121+
122+
SetHistory("someway", "noway", "yahway");
123+
124+
Test("nnnyahway", Keys(
125+
_.Ctrl_r, "way",
126+
CheckThat(() => AssertScreenIs(2,
127+
TokenClassification.Command, "yah",
128+
emphasisColors, "way",
129+
NextLine,
130+
statusColors, "bck-i-search: way_")),
131+
_.Ctrl_r,
132+
CheckThat(() => AssertScreenIs(2,
133+
TokenClassification.Command, "no",
134+
emphasisColors, "way",
135+
NextLine,
136+
statusColors, "bck-i-search: way_")),
137+
_.Ctrl_r,
138+
CheckThat(() => AssertScreenIs(2,
139+
TokenClassification.Command, "some",
140+
emphasisColors, "way",
141+
NextLine,
142+
statusColors, "bck-i-search: way_")),
143+
_.Ctrl_s,
144+
CheckThat(() => AssertScreenIs(2,
145+
TokenClassification.Command, "no",
146+
emphasisColors, "way",
147+
NextLine,
148+
statusColors, "fwd-i-search: way_")),
149+
_.Ctrl_s,
150+
CheckThat(() => AssertScreenIs(2,
151+
TokenClassification.Command, "yah",
152+
emphasisColors, "way",
153+
NextLine,
154+
statusColors, "fwd-i-search: way_")),
155+
_.Ctrl_s,
156+
CheckThat(() => AssertScreenIs(2,
157+
TokenClassification.Command, "yahway",
158+
NextLine,
159+
statusColors, "failed-fwd-i-search: way_")),
160+
161+
// Abort the history search.
162+
_.Ctrl_g, CheckThat(() => AssertLineIs(string.Empty)),
163+
// Search again and escape from the search.
164+
_.Ctrl_r, "yah",
165+
_.Escape, CheckThat(() => AssertScreenIs(1, TokenClassification.Command, "yahway")),
166+
// We should be able to edit the line, because we are in Edit mode.
167+
"nnn"));
84168
}
85169

86170
[SkippableFact]

0 commit comments

Comments
 (0)