Skip to content

Commit 8483f0e

Browse files
committed
Adding 'o', 'O', and 'J' in Vi-Mode.
1 parent 38c4a70 commit 8483f0e

File tree

3 files changed

+164
-5
lines changed

3 files changed

+164
-5
lines changed

PSReadLine/KeyBindings.vi.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ private static KeyHandler MakeViKeyHandler(Action<ConsoleKeyInfo?, object> actio
142142
{ Keys.L, MakeViKeyHandler(ForwardChar, "ForwardChar") },
143143
{ Keys.M, MakeViKeyHandler(Ding, "Ignore") },
144144
{ Keys.N, MakeViKeyHandler(RepeatSearch, "RepeatSearch") },
145-
{ Keys.O, MakeViKeyHandler(Ding, "Ignore") },
145+
{ Keys.O, MakeViKeyHandler(ViAppendLine, "ViAppendLine") },
146146
{ Keys.P, MakeViKeyHandler(PasteAfter, "PasteAfter") },
147147
{ Keys.Q, MakeViKeyHandler(Ding, "Ignore") },
148148
{ Keys.R, MakeViKeyHandler(ReplaceCharInPlace, "ReplaceCharInPlace") },
@@ -163,12 +163,12 @@ private static KeyHandler MakeViKeyHandler(Action<ConsoleKeyInfo?, object> actio
163163
{ Keys.ucG, MakeViKeyHandler(Ding, "Ignore") },
164164
{ Keys.ucH, MakeViKeyHandler(Ding, "Ignore") },
165165
{ Keys.ucI, MakeViKeyHandler(ViInsertAtBegining, "ViInsertAtBegining") },
166-
{ Keys.ucJ, MakeViKeyHandler(Ding, "Ignore") },
166+
{ Keys.ucJ, MakeViKeyHandler(ViJoinLines, "ViJoinLines") },
167167
{ Keys.ucK, MakeViKeyHandler(Ding, "Ignore") },
168168
{ Keys.ucL, MakeViKeyHandler(Ding, "Ignore") },
169169
{ Keys.ucM, MakeViKeyHandler(Ding, "Ignore") },
170170
{ Keys.ucN, MakeViKeyHandler(RepeatSearchBackward, "RepeatSearchBackward") },
171-
{ Keys.ucO, MakeViKeyHandler(BeginningOfLine, "BeginningOfLine") },
171+
{ Keys.ucO, MakeViKeyHandler(ViInsertLine, "ViInsertPhrase") },
172172
{ Keys.ucP, MakeViKeyHandler(PasteBefore, "PasteBefore") },
173173
{ Keys.ucQ, MakeViKeyHandler(Ding, "Ignore") },
174174
{ Keys.ucR, MakeViKeyHandler(ViReplaceUntilEsc, "ViReplaceUntilEsc") },

PSReadLine/ReadLine.vi.cs

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ public static void ViCommandMode(ConsoleKeyInfo? key = null, object arg = null)
368368
}
369369

370370
/// <summary>
371-
/// Switch to Insert move.
371+
/// Switch to Insert mode.
372372
/// </summary>
373373
public static void ViInsertMode(ConsoleKeyInfo? key = null, object arg = null)
374374
{
@@ -416,7 +416,8 @@ public static void ViInsertAtBegining(ConsoleKeyInfo? key = null, object arg = n
416416
/// <summary>
417417
/// Switch to Insert mode and position the cursor at the end of the line.
418418
/// </summary>
419-
public static void ViInsertAtEnd(ConsoleKeyInfo? key = null, object arg = null)
419+
public static void
420+
ViInsertAtEnd(ConsoleKeyInfo? key = null, object arg = null)
420421
{
421422
ViInsertMode(key, arg);
422423
EndOfLine(key, arg);
@@ -970,5 +971,106 @@ public static void ViAcceptLineOrExit(ConsoleKeyInfo? key = null, object arg = n
970971
ViExit(key, arg);
971972
}
972973
}
974+
975+
/// <summary>
976+
/// A new line is inserted above the current line.
977+
/// </summary>
978+
[SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
979+
public static void ViInsertLine(ConsoleKeyInfo? key = null, object arg = null)
980+
{
981+
_singleton._groupUndoHelper.StartGroup(ViInsertLine, arg);
982+
_singleton.MoveToBeginningOfPhrase();
983+
_singleton._buffer.Insert(_singleton._current, '\n');
984+
_singleton._current = Math.Max(0, _singleton._current - 1);
985+
_singleton.SaveEditItem(EditItemInsertChar.Create( '\n', _singleton._current));
986+
_singleton.Render();
987+
ViInsertMode();
988+
}
989+
990+
private void MoveToBeginningOfPhrase()
991+
{
992+
while (!IsAtBeginningOfPhrase())
993+
{
994+
_current--;
995+
}
996+
}
997+
998+
private bool IsAtBeginningOfPhrase()
999+
{
1000+
if (_current == 0)
1001+
{
1002+
return true;
1003+
}
1004+
if (_buffer[_current - 1] == '\n')
1005+
{
1006+
return true;
1007+
}
1008+
return false;
1009+
}
1010+
1011+
/// <summary>
1012+
/// A new line is inserted below the current line.
1013+
/// </summary>
1014+
[SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
1015+
public static void ViAppendLine(ConsoleKeyInfo? key = null, object arg = null)
1016+
{
1017+
_singleton._groupUndoHelper.StartGroup(ViInsertLine, arg);
1018+
_singleton.MoveToEndOfPhrase();
1019+
if (_singleton.IsAtEndOfLine(_singleton._current))
1020+
{
1021+
_singleton._buffer.Append('\n');
1022+
}
1023+
else
1024+
{
1025+
_singleton._buffer.Insert(++_singleton._current, '\n');
1026+
}
1027+
_singleton._current++;
1028+
_singleton.SaveEditItem(EditItemInsertChar.Create('\n', _singleton._current));
1029+
_singleton.Render();
1030+
ViInsertWithAppend();
1031+
}
1032+
1033+
private void MoveToEndOfPhrase()
1034+
{
1035+
while (!IsAtEndOfPhrase())
1036+
{
1037+
_current++;
1038+
}
1039+
}
1040+
1041+
private bool IsAtEndOfPhrase()
1042+
{
1043+
if (_buffer.Length == 0 || _current == _buffer.Length + ViEndOfLineFactor)
1044+
{
1045+
return true;
1046+
}
1047+
if (_buffer[_current] == '\n')
1048+
{
1049+
return true;
1050+
}
1051+
return false;
1052+
}
1053+
1054+
/// <summary>
1055+
/// Joins 2 lines.
1056+
/// </summary>
1057+
[SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
1058+
public static void ViJoinLines(ConsoleKeyInfo? key = null, object arg = null)
1059+
{
1060+
_singleton.MoveToEndOfPhrase();
1061+
if (_singleton.IsAtEndOfLine(_singleton._current))
1062+
{
1063+
Ding();
1064+
}
1065+
else
1066+
{
1067+
_singleton._buffer[_singleton._current] = ' ';
1068+
_singleton._groupUndoHelper.StartGroup(ViJoinLines, arg);
1069+
_singleton.SaveEditItem(EditItemDelete.Create("\n", _singleton._current));
1070+
_singleton.SaveEditItem(EditItemInsertChar.Create(' ', _singleton._current));
1071+
_singleton._groupUndoHelper.EndGroup();
1072+
_singleton.Render();
1073+
}
1074+
}
9731075
}
9741076
}

UnitTestPSReadLine/BasicEditingTest.VI.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ public void ViTestMisc()
578578
"uu"
579579
));
580580
}
581+
581582
[TestMethod]
582583
public void ViTestChange()
583584
{
@@ -668,5 +669,61 @@ public void ViTestChange()
668669
_.Escape, _.Dollar, 'i', _.Dollar, CheckThat(() => AssertCursorLeftIs(1))
669670
));
670671
}
672+
673+
[TestMethod]
674+
public void ViTestInsertLine()
675+
{
676+
TestSetup(KeyMode.Vi);
677+
678+
Test("line1\n", Keys(
679+
_.Escape, "Oline1", CheckThat(() => AssertCursorLeftIs(5))
680+
));
681+
682+
Test("\nline1", Keys(
683+
_.Escape, "oline1", CheckThat(() => AssertCursorLeftIs(8)), CheckThat(() => AssertLineIs("\nline1")),
684+
_.Escape, CheckThat(() => AssertCursorLeftIs(7))
685+
));
686+
687+
Test("", Keys(
688+
"line2", _.Escape, CheckThat(() => AssertLineIs("line2")),
689+
"Oline1", _.Escape, CheckThat(() => AssertLineIs("line1\nline2")),
690+
"joline3", _.Escape, CheckThat(() => AssertLineIs("line1\nline2\nline3")),
691+
'u', CheckThat(() => AssertLineIs("line1\nline2")),
692+
'u', CheckThat(() => AssertLineIs("line2")),
693+
'u', CheckThat(() => AssertLineIs("line")),
694+
"uuuu"
695+
));
696+
697+
Test("", Keys(
698+
"line2", _.Escape, '0', CheckThat(() => AssertLineIs("line2")),
699+
"Oline1", _.Escape, CheckThat(() => AssertLineIs("line1\nline2")),
700+
'j', _.Dollar, "oline3", _.Escape, CheckThat(() => AssertLineIs("line1\nline2\nline3")),
701+
'u', CheckThat(() => AssertLineIs("line1\nline2")),
702+
'u', CheckThat(() => AssertLineIs("line2")),
703+
'u', CheckThat(() => AssertLineIs("line")),
704+
"uuuu"
705+
));
706+
}
707+
708+
[TestMethod]
709+
public void ViTestJoinLines()
710+
{
711+
Test("", Keys(
712+
"line1", _.Escape, "oline2", CheckThat(() => AssertLineIs("line1\nline2")),
713+
_.Escape, "kJ", CheckThat(() => AssertLineIs("line1 line2")),
714+
'u', CheckThat(() => AssertLineIs("line1\nline2")),
715+
'u', CheckThat(() => AssertLineIs("line1")),
716+
'u', CheckThat(() => AssertLineIs("line")),
717+
"uuuu"
718+
));
719+
720+
Test("", Keys(
721+
"line1", _.Escape, "oline2", CheckThat(() => AssertLineIs("line1\nline2")),
722+
_.Escape, _.Dollar, "J", CheckThat(() => AssertLineIs("line1\nline2")),
723+
'u', CheckThat(() => AssertLineIs("line1")),
724+
'u', CheckThat(() => AssertLineIs("line")),
725+
"uuuu"
726+
));
727+
}
671728
}
672729
}

0 commit comments

Comments
 (0)