mirror of
https://github.com/PowerShell/PSReadLine
synced 2026-06-08 12:12:13 +00:00
[vi-mode] Undo now leaves the cursor under the position at the start of the deletion (#2045)
This commit is contained in:
@@ -102,7 +102,7 @@ namespace Microsoft.PowerShell
|
||||
/// </summary>
|
||||
public static void ForwardDeleteInput(ConsoleKeyInfo? key = null, object arg = null)
|
||||
{
|
||||
ForwardDeleteImpl(_singleton._buffer.Length);
|
||||
ForwardDeleteImpl(_singleton._buffer.Length, ForwardDeleteInput);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -111,7 +111,7 @@ namespace Microsoft.PowerShell
|
||||
/// </summary>
|
||||
public static void ForwardDeleteLine(ConsoleKeyInfo? key = null, object arg = null)
|
||||
{
|
||||
ForwardDeleteImpl(GetEndOfLogicalLinePos(_singleton._current) + 1);
|
||||
ForwardDeleteImpl(GetEndOfLogicalLinePos(_singleton._current) + 1, ForwardDeleteLine);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -119,7 +119,7 @@ namespace Microsoft.PowerShell
|
||||
/// but does not put the deleted text in the kill ring.
|
||||
/// </summary>
|
||||
/// <param name="endPosition">0-based offset to one character past the end of the text.</param>
|
||||
private static void ForwardDeleteImpl(int endPosition)
|
||||
private static void ForwardDeleteImpl(int endPosition, Action<ConsoleKeyInfo?, object> instigator)
|
||||
{
|
||||
var current = _singleton._current;
|
||||
var buffer = _singleton._buffer;
|
||||
@@ -128,7 +128,15 @@ namespace Microsoft.PowerShell
|
||||
{
|
||||
int length = endPosition - current;
|
||||
var str = buffer.ToString(current, length);
|
||||
_singleton.SaveEditItem(EditItemDelete.Create(str, current));
|
||||
|
||||
_singleton.SaveEditItem(
|
||||
EditItemDelete.Create(
|
||||
str,
|
||||
current,
|
||||
instigator,
|
||||
instigatorArg: null,
|
||||
!InViEditMode()));
|
||||
|
||||
buffer.Remove(current, length);
|
||||
_singleton.Render();
|
||||
}
|
||||
@@ -152,13 +160,13 @@ namespace Microsoft.PowerShell
|
||||
BackwardDeleteSubstring(position, BackwardDeleteLine);
|
||||
}
|
||||
|
||||
private static void BackwardDeleteSubstring(int position, Action<ConsoleKeyInfo?, object> instigator = null)
|
||||
private static void BackwardDeleteSubstring(int position, Action<ConsoleKeyInfo?, object> instigator)
|
||||
{
|
||||
if (_singleton._current > position)
|
||||
{
|
||||
var count = _singleton._current - position;
|
||||
|
||||
_singleton.RemoveTextToViRegister(position, count, instigator);
|
||||
|
||||
_singleton.RemoveTextToViRegister(position, count, instigator, arg: null, !InViEditMode());
|
||||
_singleton._current = position;
|
||||
_singleton.Render();
|
||||
}
|
||||
@@ -184,7 +192,7 @@ namespace Microsoft.PowerShell
|
||||
|
||||
int startDeleteIndex = _singleton._current - qty;
|
||||
|
||||
_singleton.RemoveTextToViRegister(startDeleteIndex, qty, BackwardDeleteChar, arg);
|
||||
_singleton.RemoveTextToViRegister(startDeleteIndex, qty, BackwardDeleteChar, arg, !InViEditMode());
|
||||
_singleton._current = startDeleteIndex;
|
||||
_singleton.Render();
|
||||
}
|
||||
@@ -205,7 +213,7 @@ namespace Microsoft.PowerShell
|
||||
{
|
||||
qty = Math.Min(qty, _singleton._buffer.Length - _singleton._current);
|
||||
|
||||
RemoveTextToViRegister(_current, qty, DeleteChar, qty);
|
||||
RemoveTextToViRegister(_current, qty, DeleteChar, qty, !InViEditMode());
|
||||
if (_current >= _buffer.Length)
|
||||
{
|
||||
_current = Math.Max(0, _buffer.Length + ViEndOfLineFactor);
|
||||
|
||||
@@ -75,7 +75,9 @@ namespace Microsoft.PowerShell
|
||||
inlineView.OnSuggestionAccepted();
|
||||
|
||||
using var _ = prediction.DisableScoped();
|
||||
Replace(0, _singleton._buffer.Length, inlineView.SuggestionText);
|
||||
|
||||
_singleton._current = _singleton._buffer.Length;
|
||||
Insert(inlineView.SuggestionText.Substring(_singleton._current));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,14 +107,17 @@ namespace Microsoft.PowerShell
|
||||
// Ignore the visual selection.
|
||||
_singleton._visualSelectionCommandCount = 0;
|
||||
|
||||
int index = _singleton._buffer.Length;
|
||||
int start = _singleton._buffer.Length;
|
||||
int index = start;
|
||||
while (numericArg-- > 0 && index < inlineView.SuggestionText.Length)
|
||||
{
|
||||
index = inlineView.FindForwardSuggestionWordPoint(index, _singleton.Options.WordDelimiters);
|
||||
}
|
||||
|
||||
inlineView.OnSuggestionAccepted();
|
||||
Replace(0, _singleton._buffer.Length, inlineView.SuggestionText.Substring(0, index));
|
||||
|
||||
_singleton._current = start;
|
||||
Insert(inlineView.SuggestionText.Substring(start, index - start));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+30
-12
@@ -458,6 +458,11 @@ namespace Microsoft.PowerShell
|
||||
_singleton.ViIndicateInsertMode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if in Vi edit mode, otherwise false.
|
||||
/// </summary>
|
||||
internal static bool InViEditMode() => _singleton.Options.EditMode == EditMode.Vi;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if in Vi Command mode, otherwise false.
|
||||
/// </summary>
|
||||
@@ -621,7 +626,13 @@ namespace Microsoft.PowerShell
|
||||
if (Char.IsLetter(c))
|
||||
{
|
||||
char newChar = Char.IsUpper(c) ? Char.ToLower(c, CultureInfo.CurrentCulture) : char.ToUpper(c, CultureInfo.CurrentCulture);
|
||||
EditItem delEditItem = EditItemDelete.Create(c.ToString(), _singleton._current);
|
||||
EditItem delEditItem = EditItemDelete.Create(
|
||||
c.ToString(),
|
||||
_singleton._current,
|
||||
InvertCase,
|
||||
arg,
|
||||
moveCursorToEndWhenUndo: false);
|
||||
|
||||
EditItem insEditItem = EditItemInsertChar.Create(newChar, _singleton._current);
|
||||
_singleton.SaveEditItem(GroupedEdit.Create(new List<EditItem>
|
||||
{
|
||||
@@ -657,21 +668,22 @@ namespace Microsoft.PowerShell
|
||||
if (cursor == bufferLength)
|
||||
--cursor; // if at end of line, swap previous two chars
|
||||
|
||||
char current = _singleton._buffer[cursor];
|
||||
char previous = _singleton._buffer[cursor - 1];
|
||||
_singleton.SaveEditItem(EditItemSwapCharacters.Create(cursor));
|
||||
_singleton.SwapCharactersImpl(cursor);
|
||||
|
||||
_singleton.StartEditGroup();
|
||||
_singleton.SaveEditItem(EditItemDelete.Create(_singleton._buffer.ToString(cursor - 1, 2), cursor - 1));
|
||||
_singleton.SaveEditItem(EditItemInsertChar.Create(current, cursor - 1));
|
||||
_singleton.SaveEditItem(EditItemInsertChar.Create(previous, cursor));
|
||||
_singleton.EndEditGroup();
|
||||
|
||||
_singleton._buffer[cursor] = previous;
|
||||
_singleton._buffer[cursor - 1] = current;
|
||||
_singleton.MoveCursor(Math.Min(cursor + 1, cursorRightLimit));
|
||||
_singleton.Render();
|
||||
}
|
||||
|
||||
private void SwapCharactersImpl(int cursor)
|
||||
{
|
||||
char current = _buffer[cursor];
|
||||
char previous = _buffer[cursor - 1];
|
||||
|
||||
_buffer[cursor] = previous;
|
||||
_buffer[cursor - 1] = current;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes text from the cursor to the first non-blank character of the line.
|
||||
/// </summary>
|
||||
@@ -1334,7 +1346,13 @@ namespace Microsoft.PowerShell
|
||||
{
|
||||
_singleton._buffer[_singleton._current] = ' ';
|
||||
_singleton._groupUndoHelper.StartGroup(ViJoinLines, arg);
|
||||
_singleton.SaveEditItem(EditItemDelete.Create("\n", _singleton._current));
|
||||
_singleton.SaveEditItem(EditItemDelete.Create(
|
||||
"\n",
|
||||
_singleton._current,
|
||||
ViJoinLines,
|
||||
arg,
|
||||
moveCursorToEndWhenUndo: false));
|
||||
|
||||
_singleton.SaveEditItem(EditItemInsertChar.Create(' ', _singleton._current));
|
||||
_singleton._groupUndoHelper.EndGroup();
|
||||
_singleton.Render();
|
||||
|
||||
@@ -65,7 +65,13 @@ namespace Microsoft.PowerShell
|
||||
{
|
||||
_singleton.StartEditGroup();
|
||||
string insStr = _singleton._buffer.ToString(startingCursor, _singleton._current - startingCursor);
|
||||
_singleton.SaveEditItem(EditItemDelete.Create(deletedStr.ToString(), startingCursor));
|
||||
_singleton.SaveEditItem(EditItemDelete.Create(
|
||||
deletedStr.ToString(),
|
||||
startingCursor,
|
||||
ViReplaceUntilEsc,
|
||||
arg,
|
||||
moveCursorToEndWhenUndo: false));
|
||||
|
||||
_singleton.SaveEditItem(EditItemInsertString.Create(insStr, startingCursor));
|
||||
_singleton.EndEditGroup();
|
||||
}
|
||||
@@ -226,7 +232,13 @@ namespace Microsoft.PowerShell
|
||||
if (_singleton._buffer.Length > 0 && nextKey.KeyStr.Length == 1)
|
||||
{
|
||||
_singleton.StartEditGroup();
|
||||
_singleton.SaveEditItem(EditItemDelete.Create(_singleton._buffer[_singleton._current].ToString(), _singleton._current));
|
||||
_singleton.SaveEditItem(EditItemDelete.Create(
|
||||
_singleton._buffer[_singleton._current].ToString(),
|
||||
_singleton._current,
|
||||
ReplaceCharInPlace,
|
||||
arg,
|
||||
moveCursorToEndWhenUndo: false));
|
||||
|
||||
_singleton.SaveEditItem(EditItemInsertString.Create(nextKey.KeyStr, _singleton._current));
|
||||
_singleton.EndEditGroup();
|
||||
|
||||
|
||||
+44
-5
@@ -258,27 +258,40 @@ namespace Microsoft.PowerShell
|
||||
private readonly string _deletedString;
|
||||
private readonly int _deleteStartPosition;
|
||||
|
||||
protected EditItemDelete(string str, int position, Action<ConsoleKeyInfo?, object> instigator, object instigatorArg)
|
||||
// The undo-delete operation will insert some text starting from the '_deleteStartPosition'.
|
||||
// The '_moveCursorToEndWhenUndo' flag specifies whether the cursor should be moved to the end of the inserted text.
|
||||
private readonly bool _moveCursorToEndWhenUndo;
|
||||
|
||||
protected EditItemDelete(string str, int position, Action<ConsoleKeyInfo?, object> instigator, object instigatorArg, bool moveCursorToEndWhenUndo)
|
||||
{
|
||||
_deletedString = str;
|
||||
_deleteStartPosition = position;
|
||||
_instigator = instigator;
|
||||
_instigatorArg = instigatorArg;
|
||||
_moveCursorToEndWhenUndo = moveCursorToEndWhenUndo;
|
||||
}
|
||||
|
||||
public static EditItem Create(string str, int position, Action<ConsoleKeyInfo?, object> instigator = null, object instigatorArg = null)
|
||||
public static EditItem Create(
|
||||
string str,
|
||||
int position,
|
||||
Action<ConsoleKeyInfo?, object> instigator = null,
|
||||
object instigatorArg = null,
|
||||
bool moveCursorToEndWhenUndo = true)
|
||||
{
|
||||
return new EditItemDelete(
|
||||
str,
|
||||
position,
|
||||
instigator,
|
||||
instigatorArg);
|
||||
instigatorArg,
|
||||
moveCursorToEndWhenUndo);
|
||||
}
|
||||
|
||||
public override void Undo()
|
||||
{
|
||||
_singleton._buffer.Insert(_deleteStartPosition, _deletedString);
|
||||
_singleton._current = _deleteStartPosition + _deletedString.Length;
|
||||
_singleton._current = _moveCursorToEndWhenUndo
|
||||
? _deleteStartPosition + _deletedString.Length
|
||||
: _deleteStartPosition;
|
||||
}
|
||||
|
||||
public override void Redo()
|
||||
@@ -297,7 +310,7 @@ namespace Microsoft.PowerShell
|
||||
private readonly int _deleteAnchor;
|
||||
|
||||
private EditItemDeleteLines(string str, int position, int anchor, Action<ConsoleKeyInfo?, object> instigator, object instigatorArg)
|
||||
: base(str, position, instigator, instigatorArg)
|
||||
: base(str, position, instigator, instigatorArg, moveCursorToEndWhenUndo: false)
|
||||
{
|
||||
_deleteAnchor = anchor;
|
||||
}
|
||||
@@ -314,6 +327,32 @@ namespace Microsoft.PowerShell
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerDisplay("SwapCharacters (position: {_swapPosition})")]
|
||||
class EditItemSwapCharacters : EditItem
|
||||
{
|
||||
private readonly int _swapPosition;
|
||||
|
||||
private EditItemSwapCharacters(int swapPosition)
|
||||
{
|
||||
_swapPosition = swapPosition;
|
||||
}
|
||||
|
||||
public static EditItem Create(int swapPosition)
|
||||
{
|
||||
return new EditItemSwapCharacters(swapPosition);
|
||||
}
|
||||
|
||||
public override void Redo()
|
||||
{
|
||||
_singleton.SwapCharactersImpl(_swapPosition);
|
||||
}
|
||||
|
||||
public override void Undo()
|
||||
{
|
||||
_singleton.SwapCharactersImpl(_swapPosition);
|
||||
}
|
||||
}
|
||||
|
||||
class GroupedEdit : EditItem
|
||||
{
|
||||
internal List<EditItem> _groupedEditItems;
|
||||
|
||||
+21
-10
@@ -70,23 +70,34 @@ namespace Microsoft.PowerShell
|
||||
_viRegister.LinewiseRecord(_buffer.ToString(range.Offset, range.Count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Remove a portion of text from the buffer, save it to the vi register
|
||||
/// and also save it to the edit list to support undo.
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <param name="instigator"></param>
|
||||
/// and also save it to the edit list to support undo.
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <param name="instigator"></param>
|
||||
/// <param name="arg"></param>
|
||||
private void RemoveTextToViRegister(int start, int count, Action<ConsoleKeyInfo?, object> instigator = null, object arg = null)
|
||||
{
|
||||
/// <param name="moveCursorToEndWhenUndoDelete">
|
||||
/// Use 'false' as the default value because this method is used a lot by VI operations,
|
||||
/// and for VI opeartions, we do NOT want to move the cursor to the end when undoing a
|
||||
/// deletion.
|
||||
/// </param>
|
||||
private void RemoveTextToViRegister(
|
||||
int start,
|
||||
int count,
|
||||
Action<ConsoleKeyInfo?, object> instigator = null,
|
||||
object arg = null,
|
||||
bool moveCursorToEndWhenUndoDelete = false)
|
||||
{
|
||||
_singleton.SaveToClipboard(start, count);
|
||||
_singleton.SaveEditItem(EditItemDelete.Create(
|
||||
_viRegister.RawText,
|
||||
start,
|
||||
instigator,
|
||||
arg));
|
||||
_singleton._buffer.Remove(start, count);
|
||||
arg,
|
||||
moveCursorToEndWhenUndoDelete));
|
||||
_singleton._buffer.Remove(start, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+60
-46
@@ -137,7 +137,7 @@ namespace Test
|
||||
Test("", Keys(
|
||||
"0123(567)9ab", _.Escape, "hhh", CheckThat(() => AssertCursorLeftIs(8)),
|
||||
'c', _.Percent, "45678", _.Escape, CheckThat(() => AssertLineIs("0123456789ab")), CheckThat(() => AssertCursorLeftIs(8)),
|
||||
'u', CheckThat(() => AssertLineIs("0123(567)9ab")), CheckThat(() => AssertCursorLeftIs(9)),
|
||||
'u', CheckThat(() => AssertLineIs("0123(567)9ab")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
'U'
|
||||
));
|
||||
Test("", Keys(
|
||||
@@ -381,8 +381,8 @@ namespace Test
|
||||
Test("0123", Keys(
|
||||
"0123", _.Escape,
|
||||
"d1h", CheckThat(() => AssertLineIs("013")),
|
||||
"ud3h", CheckThat(() => AssertLineIs("3")),
|
||||
"ud4h", CheckThat(() => AssertLineIs("3")),
|
||||
"u$d3h", CheckThat(() => AssertLineIs("3")),
|
||||
"u$d4h", CheckThat(() => AssertLineIs("3")),
|
||||
"u0dl", CheckThat(() => AssertLineIs("123")),
|
||||
"u0d4l", CheckThat(() => AssertLineIs("")),
|
||||
"u0d5l", CheckThat(() => AssertLineIs("")),
|
||||
@@ -432,20 +432,20 @@ namespace Test
|
||||
Test("nslookup www.google.com", Keys(
|
||||
"nslookup www", _.Period, "google", _.Period, "com", _.Escape,
|
||||
"d1b", CheckThat(() => AssertLineIs("nslookup www.google.m")),
|
||||
"ud2b", CheckThat(() => AssertLineIs("nslookup www.googlem")),
|
||||
"ud3b", CheckThat(() => AssertLineIs("nslookup www.m")),
|
||||
"ud4b", CheckThat(() => AssertLineIs("nslookup wwwm")),
|
||||
"ud5b", CheckThat(() => AssertLineIs("nslookup m")),
|
||||
"ud6b", CheckThat(() => AssertLineIs("m")),
|
||||
"ud7b", CheckThat(() => AssertLineIs("m")),
|
||||
"u$d2b", CheckThat(() => AssertLineIs("nslookup www.googlem")),
|
||||
"u$d3b", CheckThat(() => AssertLineIs("nslookup www.m")),
|
||||
"u$d4b", CheckThat(() => AssertLineIs("nslookup wwwm")),
|
||||
"u$d5b", CheckThat(() => AssertLineIs("nslookup m")),
|
||||
"u$d6b", CheckThat(() => AssertLineIs("m")),
|
||||
"u$d7b", CheckThat(() => AssertLineIs("m")),
|
||||
'u'
|
||||
));
|
||||
|
||||
Test("nslookup www.google.com", Keys(
|
||||
"nslookup www", _.Period, "google", _.Period, "com", _.Escape,
|
||||
"d1B", CheckThat(() => AssertLineIs("nslookup m")),
|
||||
"ud2B", CheckThat(() => AssertLineIs("m")),
|
||||
"ud3B", CheckThat(() => AssertLineIs("m")),
|
||||
"u$d2B", CheckThat(() => AssertLineIs("m")),
|
||||
"u$d3B", CheckThat(() => AssertLineIs("m")),
|
||||
'u'
|
||||
));
|
||||
|
||||
@@ -529,6 +529,22 @@ namespace Test
|
||||
));
|
||||
}
|
||||
|
||||
// Defect #1673
|
||||
[SkippableFact]
|
||||
public void ViDelete_UndoCursorPosition()
|
||||
{
|
||||
TestSetup(KeyMode.Vi);
|
||||
|
||||
Test("one", Keys(
|
||||
"one", _.Escape,
|
||||
"h", // move back to the 'n' character
|
||||
"x", CheckThat(() => AssertLineIs("oe")),
|
||||
|
||||
// undo
|
||||
"u", CheckThat(() => AssertCursorLeftIs(1))
|
||||
));
|
||||
}
|
||||
|
||||
// Defect #1674
|
||||
[SkippableFact]
|
||||
public void ViDeleteToCharBack()
|
||||
@@ -685,9 +701,9 @@ namespace Test
|
||||
Test("0 2+4 6", Keys(
|
||||
"0 2+4 6", _.Escape, CheckThat(() => AssertLineIs("0 2+4 6")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
"dB", CheckThat(() => AssertLineIs("0 6")), CheckThat(() => AssertCursorLeftIs(2)),
|
||||
"u", CheckThat(() => AssertLineIs("0 2+4 6")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
"2dB", CheckThat(() => AssertLineIs("6")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"u", CheckThat(() => AssertLineIs("0 2+4 6")), CheckThat(() => AssertCursorLeftIs(6))
|
||||
"u", CheckThat(() => AssertLineIs("0 2+4 6")), CheckThat(() => AssertCursorLeftIs(2)),
|
||||
"$2dB", CheckThat(() => AssertLineIs("6")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"u", CheckThat(() => AssertLineIs("0 2+4 6")), CheckThat(() => AssertCursorLeftIs(0))
|
||||
));
|
||||
|
||||
Test("0 2+4 6", Keys(
|
||||
@@ -697,7 +713,7 @@ namespace Test
|
||||
"u0ldE", CheckThat(() => AssertLineIs("0 6")), CheckThat(() => AssertCursorLeftIs(1)),
|
||||
"u0l2dE", CheckThat(() => AssertLineIs("0")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"u03dE", CheckThat(() => AssertLineIs("")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"u", CheckThat(() => AssertLineIs("0 2+4 6")), CheckThat(() => AssertCursorLeftIs(6))
|
||||
"u", CheckThat(() => AssertLineIs("0 2+4 6")), CheckThat(() => AssertCursorLeftIs(0))
|
||||
));
|
||||
|
||||
Test("0 2+4 6", Keys(
|
||||
@@ -708,7 +724,7 @@ namespace Test
|
||||
"u0l2dW", CheckThat(() => AssertLineIs("06")), CheckThat(() => AssertCursorLeftIs(1)),
|
||||
"u0l3dW", CheckThat(() => AssertLineIs("0")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"u03dW", CheckThat(() => AssertLineIs("")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"u", CheckThat(() => AssertLineIs("0 2+4 6")), CheckThat(() => AssertCursorLeftIs(6))
|
||||
"u", CheckThat(() => AssertLineIs("0 2+4 6")), CheckThat(() => AssertCursorLeftIs(0))
|
||||
));
|
||||
}
|
||||
|
||||
@@ -738,7 +754,7 @@ namespace Test
|
||||
Test("(1{3{5)789)b}c", Keys(
|
||||
"(1{3{5)789)b}c", _.Escape, CheckThat(() => AssertLineIs("(1{3{5)789)b}c")), CheckThat(() => AssertCursorLeftIs(13)),
|
||||
"hd", _.Percent, CheckThat(() => AssertLineIs("(1{3c")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
"u", CheckThat(() => AssertLineIs("(1{3{5)789)b}c")), CheckThat(() => AssertCursorLeftIs(13))
|
||||
"u", CheckThat(() => AssertLineIs("(1{3{5)789)b}c")), CheckThat(() => AssertCursorLeftIs(4))
|
||||
));
|
||||
|
||||
Test("(1{3[5)7}9)b]", Keys(
|
||||
@@ -750,13 +766,13 @@ namespace Test
|
||||
Test("(1{3[5)7}9)b]c", Keys(
|
||||
"(1{3[5)7}9)b]c", _.Escape, CheckThat(() => AssertLineIs("(1{3[5)7}9)b]c")), CheckThat(() => AssertCursorLeftIs(13)),
|
||||
"hhhhhd", _.Percent, CheckThat(() => AssertLineIs("(19)b]c")), CheckThat(() => AssertCursorLeftIs(2)),
|
||||
"u", CheckThat(() => AssertLineIs("(1{3[5)7}9)b]c")), CheckThat(() => AssertCursorLeftIs(9))
|
||||
"u", CheckThat(() => AssertLineIs("(1{3[5)7}9)b]c")), CheckThat(() => AssertCursorLeftIs(2))
|
||||
));
|
||||
|
||||
Test("(1{3[5)7}9)b]d", Keys(
|
||||
"(1{3[5)7}9)b]d", _.Escape, CheckThat(() => AssertLineIs("(1{3[5)7}9)b]d")), CheckThat(() => AssertCursorLeftIs(13)),
|
||||
"h", _.Percent, "d", _.Percent, CheckThat(() => AssertLineIs("(1{3d")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
"u", CheckThat(() => AssertLineIs("(1{3[5)7}9)b]d")), CheckThat(() => AssertCursorLeftIs(13))
|
||||
"u", CheckThat(() => AssertLineIs("(1{3[5)7}9)b]d")), CheckThat(() => AssertCursorLeftIs(4))
|
||||
));
|
||||
|
||||
Test("(1{3[5)7}9)b]", Keys(
|
||||
@@ -770,7 +786,7 @@ namespace Test
|
||||
Test("(1{3[5)7}9)b]c", Keys(
|
||||
"(1{3[5)7}9)b]c", _.Escape, CheckThat(() => AssertLineIs("(1{3[5)7}9)b]c")), CheckThat(() => AssertCursorLeftIs(13)),
|
||||
"hhhhh", _.Percent, "d", _.Percent, CheckThat(() => AssertLineIs("(19)b]c")), CheckThat(() => AssertCursorLeftIs(2)),
|
||||
"u", CheckThat(() => AssertLineIs("(1{3[5)7}9)b]c")), CheckThat(() => AssertCursorLeftIs(9))
|
||||
"u", CheckThat(() => AssertLineIs("(1{3[5)7}9)b]c")), CheckThat(() => AssertCursorLeftIs(2))
|
||||
));
|
||||
|
||||
Test("012 [ 67 ] bc", Keys(
|
||||
@@ -779,7 +795,7 @@ namespace Test
|
||||
_.Percent, CheckThat(() => AssertCursorLeftIs(4)),
|
||||
_.Percent, CheckThat(() => AssertCursorLeftIs(9)),
|
||||
'd', _.Percent, CheckThat(() => AssertLineIs("012 bc")),
|
||||
"uh", CheckThat(() => AssertLineIs("012 [ 67 ] bc")), CheckThat(() => AssertCursorLeftIs(9)),
|
||||
"u", CheckThat(() => AssertLineIs("012 [ 67 ] bc")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
'c', _.Percent, "99", _.Escape, CheckThat(() => AssertLineIs("012 99 bc")),
|
||||
'u'
|
||||
));
|
||||
@@ -790,10 +806,9 @@ namespace Test
|
||||
_.Percent, CheckThat(() => AssertCursorLeftIs(4)),
|
||||
_.Percent, CheckThat(() => AssertCursorLeftIs(9)),
|
||||
'd', _.Percent, CheckThat(() => AssertLineIs("012 bc")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
'u', CheckThat(() => AssertLineIs("012 { 67 } bc")), CheckThat(() => AssertCursorLeftIs(10)),
|
||||
'h', _.Percent, CheckThat(() => AssertCursorLeftIs(4)),
|
||||
'u', CheckThat(() => AssertLineIs("012 { 67 } bc")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
'd', _.Percent, CheckThat(() => AssertLineIs("012 bc")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
'u', CheckThat(() => AssertCursorLeftIs(10))
|
||||
'u', CheckThat(() => AssertCursorLeftIs(4))
|
||||
));
|
||||
|
||||
Test("012 ( 67 ) bc", Keys(
|
||||
@@ -802,10 +817,9 @@ namespace Test
|
||||
_.Percent, CheckThat(() => AssertCursorLeftIs(4)),
|
||||
_.Percent, CheckThat(() => AssertCursorLeftIs(9)),
|
||||
'd', _.Percent, CheckThat(() => AssertLineIs("012 bc")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
'u', CheckThat(() => AssertLineIs("012 ( 67 ) bc")), CheckThat(() => AssertCursorLeftIs(10)),
|
||||
'h', _.Percent, CheckThat(() => AssertCursorLeftIs(4)),
|
||||
'u', CheckThat(() => AssertLineIs("012 ( 67 ) bc")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
'd', _.Percent, CheckThat(() => AssertLineIs("012 bc")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
'u', CheckThat(() => AssertCursorLeftIs(10))
|
||||
'u', CheckThat(() => AssertCursorLeftIs(4))
|
||||
));
|
||||
}
|
||||
|
||||
@@ -865,9 +879,9 @@ namespace Test
|
||||
Test("012 45", Keys(
|
||||
"012 45", _.Escape,
|
||||
"0cwabc", _.Escape, CheckThat(() => AssertLineIs("abc 45")),
|
||||
"u", CheckThat(() => AssertLineIs("012 45")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
"u", CheckThat(() => AssertLineIs("012 45")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"0cwabc", _.Escape, CheckThat(() => AssertLineIs("abc 45")),
|
||||
"u", CheckThat(() => AssertCursorLeftIs(4)),
|
||||
"u", CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"0cwabc", _.Escape, "wcwef", _.Escape, CheckThat(() => AssertLineIs("abc ef")),
|
||||
"uu", CheckThat(() => AssertLineIs("012 45")),
|
||||
"02cwabcdef", _.Escape, CheckThat(() => AssertLineIs("abcdef")),
|
||||
@@ -1037,25 +1051,25 @@ namespace Test
|
||||
Test("0123456", Keys(
|
||||
"0123456", _.Escape, CheckThat(() => AssertLineIs("0123456")),
|
||||
"0cf6abc", _.Escape, CheckThat(() => AssertLineIs("abc")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"0cf5abc", _.Escape, CheckThat(() => AssertLineIs("abc6")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"0lcf6abc", _.Escape, CheckThat(() => AssertLineIs("0abc")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
"cf6abc", _.Escape, CheckThat(() => AssertLineIs("0123456bc")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(1)),
|
||||
"$cf6abc", _.Escape, CheckThat(() => AssertLineIs("0123456bc")),
|
||||
'u'
|
||||
));
|
||||
|
||||
Test("0123456", Keys(
|
||||
"0123456", _.Escape, CheckThat(() => AssertLineIs("0123456")),
|
||||
"cF0abc", _.Escape, CheckThat(() => AssertLineIs("abc6")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
"cF1abc", _.Escape, CheckThat(() => AssertLineIs("0abc6")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
"hcF0abc", _.Escape, CheckThat(() => AssertLineIs("abc56")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(5)),
|
||||
"hcF1abc", _.Escape, CheckThat(() => AssertLineIs("0abc456")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(4)),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"$cF1abc", _.Escape, CheckThat(() => AssertLineIs("0abc6")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(1)),
|
||||
"$hcF0abc", _.Escape, CheckThat(() => AssertLineIs("abc56")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"$hhcF1abc", _.Escape, CheckThat(() => AssertLineIs("0abc456")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(1)),
|
||||
"0cF0abc", _.Escape, CheckThat(() => AssertLineIs("0bc123456")),
|
||||
'u'
|
||||
));
|
||||
@@ -1063,19 +1077,19 @@ namespace Test
|
||||
Test("0123456", Keys(
|
||||
"0123456", _.Escape, CheckThat(() => AssertLineIs("0123456")),
|
||||
"0ct6abc", _.Escape, CheckThat(() => AssertLineIs("abc6")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"0lct6abc", _.Escape, CheckThat(() => AssertLineIs("0abc6")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
"ct6abc", _.Escape, CheckThat(() => AssertLineIs("0123456bc")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(1)),
|
||||
"$ct6abc", _.Escape, CheckThat(() => AssertLineIs("0123456bc")),
|
||||
'u'
|
||||
));
|
||||
|
||||
Test("0123456", Keys(
|
||||
"0123456", _.Escape, CheckThat(() => AssertLineIs("0123456")),
|
||||
"cT1abc", _.Escape, CheckThat(() => AssertLineIs("01abc6")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
"hcT1abc", _.Escape, CheckThat(() => AssertLineIs("01abc56")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(5)),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(2)),
|
||||
"$hcT1abc", _.Escape, CheckThat(() => AssertLineIs("01abc56")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(2)),
|
||||
"0cT0abc", _.Escape, CheckThat(() => AssertLineIs("0bc123456")),
|
||||
'u'
|
||||
));
|
||||
|
||||
@@ -200,6 +200,36 @@ namespace Test
|
||||
Test("exit", Keys("foo", _.Home, Enumerable.Repeat(_.Ctrl_d, 4), InputAcceptedNow));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void SelectAndDelete()
|
||||
{
|
||||
TestSetup(KeyMode.Cmd);
|
||||
|
||||
Test("abcde", Keys(
|
||||
"abcde",
|
||||
CheckThat(() => AssertCursorLeftIs(5)),
|
||||
_.Shift_LeftArrow, _.Shift_LeftArrow, _.Shift_LeftArrow,
|
||||
_.Backspace,
|
||||
CheckThat(() => AssertLineIs("ab")),
|
||||
CheckThat(() => AssertCursorLeftIs(2)),
|
||||
_.Ctrl_z,
|
||||
CheckThat(() => AssertLineIs("abcde")),
|
||||
CheckThat(() => AssertCursorLeftIs(5))));
|
||||
|
||||
Test("abcde", Keys(
|
||||
"abcde", _.Home,
|
||||
CheckThat(() => AssertCursorLeftIs(0)),
|
||||
_.RightArrow, _.RightArrow,
|
||||
CheckThat(() => AssertCursorLeftIs(2)),
|
||||
_.Shift_RightArrow, _.Shift_RightArrow,
|
||||
_.Delete,
|
||||
CheckThat(() => AssertLineIs("abe")),
|
||||
CheckThat(() => AssertCursorLeftIs(2)),
|
||||
_.Ctrl_z,
|
||||
CheckThat(() => AssertLineIs("abcde")),
|
||||
CheckThat(() => AssertCursorLeftIs(4))));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void SwapCharacters()
|
||||
{
|
||||
@@ -212,7 +242,7 @@ namespace Test
|
||||
Test("abc", Keys(
|
||||
"abc", CheckThat(() => AssertLineIs("abc")),
|
||||
_.Ctrl_t, CheckThat(() => AssertLineIs("acb")),
|
||||
_.Ctrl_Underbar
|
||||
_.Ctrl_Underbar, CheckThat(() => AssertCursorLeftIs(3))
|
||||
));
|
||||
|
||||
Test("abcd", Keys(
|
||||
|
||||
@@ -364,6 +364,36 @@ namespace Test
|
||||
));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void ViDefect2408()
|
||||
{
|
||||
TestSetup(KeyMode.Vi);
|
||||
using var disp = SetPrediction(PredictionSource.History, PredictionViewStyle.InlineView);
|
||||
|
||||
SetHistory("echo -bar");
|
||||
Test("ech", Keys(
|
||||
"abcd",
|
||||
CheckThat(() => AssertScreenIs(1,
|
||||
TokenClassification.Command, "abcd")),
|
||||
_.Escape, 'S',
|
||||
CheckThat(() => AssertLineIs(string.Empty)),
|
||||
CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"ech",
|
||||
CheckThat(() => AssertScreenIs(1,
|
||||
TokenClassification.Command, "ech",
|
||||
TokenClassification.InlinePrediction, "o -bar")),
|
||||
_.RightArrow,
|
||||
CheckThat(() => AssertScreenIs(1,
|
||||
TokenClassification.Command, "echo",
|
||||
TokenClassification.None, ' ',
|
||||
TokenClassification.Parameter, "-bar")),
|
||||
CheckThat(() => AssertCursorLeftIs(9)),
|
||||
_.Ctrl_z,
|
||||
CheckThat(() => AssertScreenIs(1,
|
||||
TokenClassification.Command, "ech",
|
||||
TokenClassification.InlinePrediction, "o -bar"))));
|
||||
}
|
||||
|
||||
private const uint MiniSessionId = 56;
|
||||
private static readonly Guid predictorId_1 = Guid.Parse("b45b5fbe-90fa-486c-9c87-e7940fdd6273");
|
||||
private static readonly Guid predictorId_2 = Guid.Parse("74a86463-033b-44a3-b386-41ee191c94be");
|
||||
|
||||
+22
-10
@@ -620,25 +620,25 @@ namespace Test
|
||||
Test("", Keys(
|
||||
"abcdefg", _.Escape, CheckThat(() => AssertLineIs("abcdefg")),
|
||||
"0dfg", CheckThat(() => AssertLineIs("")),
|
||||
'u', CheckThat(() => AssertLineIs("abcdefg")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
'u', CheckThat(() => AssertLineIs("abcdefg")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"0dff", CheckThat(() => AssertLineIs("g")),
|
||||
'u', CheckThat(() => AssertLineIs("abcdefg")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
'u', CheckThat(() => AssertLineIs("abcdefg")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"0dfg"
|
||||
));
|
||||
|
||||
Test("g", Keys(
|
||||
Test("bcdefg", Keys(
|
||||
"abcdefg", _.Escape, CheckThat(() => AssertLineIs("abcdefg")),
|
||||
"dFa", _.Escape, CheckThat(() => AssertLineIs("g")),
|
||||
'u', CheckThat(() => AssertCursorLeftIs(6)),
|
||||
"dFb", CheckThat(() => AssertLineIs("ag")),
|
||||
'u', CheckThat(() => AssertCursorLeftIs(6)),
|
||||
'u', CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"$dFb", CheckThat(() => AssertLineIs("ag")),
|
||||
'u', CheckThat(() => AssertCursorLeftIs(1)),
|
||||
"dFa"
|
||||
));
|
||||
|
||||
Test("0123456", Keys(
|
||||
"0123456", _.Escape, CheckThat(() => AssertLineIs("0123456")),
|
||||
"0dt6", CheckThat(() => AssertLineIs("6")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(0)),
|
||||
"0dt5", CheckThat(() => AssertLineIs("56")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")),
|
||||
"0ldt6", CheckThat(() => AssertLineIs("06")),
|
||||
@@ -650,9 +650,9 @@ namespace Test
|
||||
Test("0123456", Keys(
|
||||
"0123456", _.Escape, CheckThat(() => AssertLineIs("0123456")),
|
||||
"dT0", CheckThat(() => AssertLineIs("06")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(6)),
|
||||
"hdT0", CheckThat(() => AssertLineIs("056")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(5)),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(1)),
|
||||
"$hdT0", CheckThat(() => AssertLineIs("056")),
|
||||
'u', CheckThat(() => AssertLineIs("0123456")), CheckThat(() => AssertCursorLeftIs(1)),
|
||||
"0dT0"
|
||||
));
|
||||
}
|
||||
@@ -666,5 +666,17 @@ namespace Test
|
||||
_.Escape, "kjw"
|
||||
));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void ViDefect1673()
|
||||
{
|
||||
TestSetup(KeyMode.Vi);
|
||||
|
||||
Test("one", Keys(
|
||||
"one", _.Escape, _.D0,
|
||||
_.x, CheckThat(() => AssertLineIs("ne")),
|
||||
_.u, CheckThat(() => AssertCursorLeftIs(0))
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Test
|
||||
_.Escape, CheckThat(() => AssertCursorLeftIs(5)),
|
||||
'b', CheckThat(() => AssertCursorLeftIs(4)),
|
||||
"dw", CheckThat(() => AssertLineIs("test")),
|
||||
"ubcw", CheckThat(() => AssertLineIs("test")),
|
||||
"ulbcw", CheckThat(() => AssertLineIs("test")),
|
||||
"[]", _.Escape, CheckThat(() => AssertLineIs("test[]")),
|
||||
'u'
|
||||
));
|
||||
@@ -59,8 +59,8 @@ namespace Test
|
||||
CheckThat(() => AssertLineIs(@"vim .\PSReadLine\VisualEditing.vi.cs")),
|
||||
_.Escape, "Bll", CheckThat(() => AssertCursorLeftIs(6)),
|
||||
"cw", _.Escape, CheckThat(() => AssertCursorLeftIs(5)), CheckThat(() => AssertLineIs(@"vim .\\VisualEditing.vi.cs")),
|
||||
'u', CheckThat(() => AssertCursorLeftIs(16)), CheckThat(() => AssertLineIs(@"vim .\PSReadLine\VisualEditing.vi.cs")),
|
||||
"bcwxx", _.Escape, CheckThat(() => AssertCursorLeftIs(7))
|
||||
'u', CheckThat(() => AssertCursorLeftIs(6)), CheckThat(() => AssertLineIs(@"vim .\PSReadLine\VisualEditing.vi.cs")),
|
||||
"cwxx", _.Escape, CheckThat(() => AssertCursorLeftIs(7))
|
||||
));
|
||||
|
||||
Test("$response.Headers['location']", Keys(
|
||||
|
||||
Reference in New Issue
Block a user