Skip to content

Commit 8b0cc85

Browse files
authored
vi-mode: Make 'D' and 'd$' delete to the end of the current logical line (#1695)
1 parent 8d74e42 commit 8b0cc85

File tree

3 files changed

+67
-10
lines changed

3 files changed

+67
-10
lines changed

PSReadLine/Position.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,16 @@ private static int GetEndOfLogicalLinePos(int current)
9393
return newCurrent;
9494
}
9595

96+
/// <summary>
97+
/// Returns the position of the end of the logical line
98+
/// for the 0-based specified line number.
99+
/// </summary>
100+
private static int GetEndOfNthLogicalLinePos(int lineIndex)
101+
{
102+
return GetEndOfLogicalLinePos(
103+
GetBeginningOfNthLinePos(lineIndex));
104+
}
105+
96106
/// <summary>
97107
/// Returns the position of the first non whitespace character in
98108
/// the current logical line as specified by the "current" position.

PSReadLine/ReadLine.vi.cs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,43 @@ public static void DeleteToEnd(ConsoleKeyInfo? key = null, object arg = null)
220220
return;
221221
}
222222

223-
_clipboard.Record(_singleton._buffer, _singleton._current, _singleton._buffer.Length - _singleton._current);
224-
_singleton.SaveEditItem(EditItemDelete.Create(
225-
_clipboard,
226-
_singleton._current,
227-
DeleteToEnd,
228-
arg
229-
));
230-
_singleton._buffer.Remove(_singleton._current, _singleton._buffer.Length - _singleton._current);
231-
_singleton._current = Math.Max(0, _singleton._buffer.Length - 1);
232-
_singleton.Render();
223+
var lineCount = _singleton.GetLogicalLineCount();
224+
var lineIndex = _singleton.GetLogicalLineNumber() - 1;
225+
226+
if (TryGetArgAsInt(arg, out var requestedLineCount, 1))
227+
{
228+
var targetLineIndex = lineIndex + requestedLineCount - 1;
229+
if (targetLineIndex >= lineCount)
230+
{
231+
targetLineIndex = lineCount - 1;
232+
}
233+
234+
var startPosition = _singleton._current;
235+
var endPosition = GetEndOfNthLogicalLinePos(targetLineIndex);
236+
237+
var length = endPosition - startPosition + 1;
238+
if (length > 0)
239+
{
240+
_clipboard.Record(_singleton._buffer, startPosition, length);
241+
_singleton.SaveEditItem(EditItemDelete.Create(
242+
_clipboard,
243+
_singleton._current,
244+
DeleteToEnd,
245+
arg));
246+
247+
_singleton._buffer.Remove(_singleton._current, length);
248+
249+
// the cursor will go back one character, unless at the beginning of the line
250+
var endOfLineCursorPos = GetEndOfLogicalLinePos(_singleton._current) - 1;
251+
var beginningOfLinePos = GetBeginningOfLinePos(_singleton._current);
252+
253+
_singleton._current = Math.Max(
254+
beginningOfLinePos,
255+
Math.Min(_singleton._current, endOfLineCursorPos));
256+
257+
_singleton.Render();
258+
}
259+
}
233260
}
234261

235262
/// <summary>

test/BasicEditingTest.VI.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,26 @@ public void ViDeleteToEndOfBuffer()
489489
));
490490
}
491491

492+
[SkippableFact]
493+
public void ViDeleteToEnd()
494+
{
495+
TestSetup(KeyMode.Vi);
496+
497+
int continuationPrefixLength = PSConsoleReadLineOptions.DefaultContinuationPrompt.Length;
498+
499+
Test("\"\no\nthree\n\"", Keys(
500+
_.DQuote, _.Enter,
501+
"one", _.Enter,
502+
"two", _.Enter,
503+
"three", _.Enter,
504+
_.DQuote, _.Escape,
505+
"kkkl", // go to the 'ne' portion of "one"
506+
// delete to the end of the next line
507+
"2d$",
508+
CheckThat(() => AssertCursorLeftIs(continuationPrefixLength + 0))
509+
));
510+
}
511+
492512
[SkippableFact]
493513
public void ViGlobDelete()
494514
{

0 commit comments

Comments
 (0)