Skip to content

#1750 - Using 'd0' to delete to start of the current logical line in a multiline buffer #2002

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Feb 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 45 additions & 9 deletions PSReadLine/BasicEditing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,36 @@ public static void CancelLine(ConsoleKeyInfo? key = null, object arg = null)
}

/// <summary>
/// Like ForwardKillLine - deletes text from the point to the end of the line,
/// Like KillLine - deletes text from the point to the end of the input,
/// but does not put the deleted text in the kill ring.
/// </summary>
public static void ForwardDeleteInput(ConsoleKeyInfo? key = null, object arg = null)
{
ForwardDeleteImpl(_singleton._buffer.Length);
}

/// <summary>
/// Deletes text from the point to the end of the current logical line,
/// but does not put the deleted text in the kill ring.
/// </summary>
public static void ForwardDeleteLine(ConsoleKeyInfo? key = null, object arg = null)
{
ForwardDeleteImpl(GetEndOfLogicalLinePos(_singleton._current) + 1);
}

/// <summary>
/// Deletes text from the cursor position to the specified end position
/// 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)
{
var current = _singleton._current;
var buffer = _singleton._buffer;
if (buffer.Length > 0 && current < buffer.Length)

if (buffer.Length > 0 && current < endPosition)
{
int length = buffer.Length - current;
int length = endPosition - current;
var str = buffer.ToString(current, length);
_singleton.SaveEditItem(EditItemDelete.Create(str, current));
buffer.Remove(current, length);
Expand All @@ -115,17 +135,33 @@ public static void ForwardDeleteLine(ConsoleKeyInfo? key = null, object arg = nu
}

/// <summary>
/// Like BackwardKillLine - deletes text from the point to the start of the line,
/// Like BackwardKillInput - deletes text from the point to the start of the input,
/// but does not put the deleted text in the kill ring.
public static void BackwardDeleteInput(ConsoleKeyInfo? key = null, object arg = null)
{
BackwardDeleteSubstring(0, BackwardDeleteInput);
}

/// <summary>
/// Like BackwardKillLine - deletes text from the point to the start of the logical line,
/// but does not put the deleted text in the kill ring.
/// </summary>
public static void BackwardDeleteLine(ConsoleKeyInfo? key = null, object arg = null)
{
if (_singleton._current > 0)
var position = GetBeginningOfLinePos(_singleton._current);
BackwardDeleteSubstring(position, BackwardDeleteLine);
}

private static void BackwardDeleteSubstring(int position, Action<ConsoleKeyInfo?, object> instigator = null)
{
if (_singleton._current > position)
{
_clipboard.Record(_singleton._buffer, 0, _singleton._current);
_singleton.SaveEditItem(EditItemDelete.Create(_clipboard, 0));
_singleton._buffer.Remove(0, _singleton._current);
_singleton._current = 0;
var count = _singleton._current - position;

_clipboard.Record(_singleton._buffer, position, count);
_singleton.SaveEditItem(EditItemDelete.Create(_clipboard, position, instigator));
_singleton._buffer.Remove(position, count);
_singleton._current = position;
_singleton.Render();
}
}
Expand Down
11 changes: 7 additions & 4 deletions PSReadLine/KeyBindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ void SetDefaultWindowsBindings()
{ Keys.CtrlY, MakeKeyHandler(Redo, "Redo") },
{ Keys.CtrlZ, MakeKeyHandler(Undo, "Undo") },
{ Keys.CtrlBackspace, MakeKeyHandler(BackwardKillWord, "BackwardKillWord") },
{ Keys.CtrlHome, MakeKeyHandler(BackwardDeleteLine, "BackwardDeleteLine") },
{ Keys.CtrlHome, MakeKeyHandler(BackwardDeleteInput, "BackwardDeleteInput") },
{ Keys.CtrlRBracket, MakeKeyHandler(GotoBrace, "GotoBrace") },
{ Keys.CtrlAltQuestion, MakeKeyHandler(ShowKeyBindings, "ShowKeyBindings") },
{ Keys.AltPeriod, MakeKeyHandler(YankLastArg, "YankLastArg") },
Expand Down Expand Up @@ -242,7 +242,7 @@ void SetDefaultWindowsBindings()
_dispatchTable.Add(Keys.CtrlSpace, MakeKeyHandler(MenuComplete, "MenuComplete"));
_dispatchTable.Add(Keys.AltF7, MakeKeyHandler(ClearHistory, "ClearHistory"));
_dispatchTable.Add(Keys.CtrlDelete, MakeKeyHandler(KillWord, "KillWord"));
_dispatchTable.Add(Keys.CtrlEnd, MakeKeyHandler(ForwardDeleteLine, "ForwardDeleteLine"));
_dispatchTable.Add(Keys.CtrlEnd, MakeKeyHandler(ForwardDeleteInput, "ForwardDeleteInput"));
_dispatchTable.Add(Keys.CtrlH, MakeKeyHandler(BackwardDeleteChar,"BackwardDeleteChar"));

// PageUp/PageDown and CtrlPageUp/CtrlPageDown bindings are supported on Windows only because they depend on the
Expand Down Expand Up @@ -294,7 +294,7 @@ void SetDefaultEmacsBindings()
{ Keys.CtrlR, MakeKeyHandler(ReverseSearchHistory, "ReverseSearchHistory") },
{ Keys.CtrlS, MakeKeyHandler(ForwardSearchHistory, "ForwardSearchHistory") },
{ Keys.CtrlT, MakeKeyHandler(SwapCharacters, "SwapCharacters") },
{ Keys.CtrlU, MakeKeyHandler(BackwardKillLine, "BackwardKillLine") },
{ Keys.CtrlU, MakeKeyHandler(BackwardKillInput, "BackwardKillInput") },
{ Keys.CtrlX, MakeKeyHandler(Chord, "ChordFirstKey") },
{ Keys.CtrlW, MakeKeyHandler(UnixWordRubout, "UnixWordRubout") },
{ Keys.CtrlY, MakeKeyHandler(Yank, "Yank") },
Expand Down Expand Up @@ -369,7 +369,7 @@ void SetDefaultEmacsBindings()
// Ctrl+X,<key> table
[Keys.CtrlX] = new Dictionary<PSKeyInfo, KeyHandler>
{
{ Keys.Backspace, MakeKeyHandler(BackwardKillLine, "BackwardKillLine") },
{ Keys.Backspace, MakeKeyHandler(BackwardKillInput, "BackwardKillInput") },
{ Keys.CtrlE, MakeKeyHandler(ViEditVisually, "ViEditVisually") },
{ Keys.CtrlU, MakeKeyHandler(Undo, "Undo") },
{ Keys.CtrlX, MakeKeyHandler(ExchangePointAndMark, "ExchangePointAndMark") },
Expand All @@ -388,9 +388,11 @@ public static KeyHandlerGroup GetDisplayGrouping(string function)
case nameof(AcceptAndGetNext):
case nameof(AcceptLine):
case nameof(AddLine):
case nameof(BackwardDeleteInput):
case nameof(BackwardDeleteChar):
case nameof(BackwardDeleteLine):
case nameof(BackwardDeleteWord):
case nameof(BackwardKillInput):
case nameof(BackwardKillLine):
case nameof(BackwardKillWord):
case nameof(CancelLine):
Expand All @@ -408,6 +410,7 @@ public static KeyHandlerGroup GetDisplayGrouping(string function)
case nameof(DeletePreviousLines):
case nameof(DeleteToEnd):
case nameof(DeleteWord):
case nameof(ForwardDeleteInput):
case nameof(ForwardDeleteLine):
case nameof(InsertLineAbove):
case nameof(InsertLineBelow):
Expand Down
12 changes: 6 additions & 6 deletions PSReadLine/KeyBindings.vi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,16 @@ private void SetDefaultViBindings()
{ Keys.CtrlSpace, MakeKeyHandler(PossibleCompletions, "PossibleCompletions") },
{ Keys.Tab, MakeKeyHandler(ViTabCompleteNext, "ViTabCompleteNext") },
{ Keys.ShiftTab, MakeKeyHandler(ViTabCompletePrevious, "ViTabCompletePrevious") },
{ Keys.CtrlU, MakeKeyHandler(BackwardDeleteLine, "BackwardDeleteLine") },
{ Keys.CtrlU, MakeKeyHandler(BackwardDeleteInput, "BackwardDeleteInput") },
{ Keys.CtrlV, MakeKeyHandler(Paste, "Paste") },
{ Keys.CtrlC, MakeKeyHandler(CancelLine, "CancelLine") },
{ Keys.CtrlL, MakeKeyHandler(ClearScreen, "ClearScreen") },
{ Keys.CtrlT, MakeKeyHandler(SwapCharacters, "SwapCharacters") },
{ Keys.CtrlY, MakeKeyHandler(Redo, "Redo") },
{ Keys.CtrlZ, MakeKeyHandler(Undo, "Undo") },
{ Keys.CtrlBackspace, MakeKeyHandler(BackwardKillWord, "BackwardKillWord") },
{ Keys.CtrlEnd, MakeKeyHandler(ForwardDeleteLine, "ForwardDeleteLine") },
{ Keys.CtrlHome, MakeKeyHandler(BackwardDeleteLine, "BackwardDeleteLine") },
{ Keys.CtrlEnd, MakeKeyHandler(ForwardDeleteInput, "ForwardDeleteInput") },
{ Keys.CtrlHome, MakeKeyHandler(BackwardDeleteInput, "BackwardDeleteInput") },
{ Keys.CtrlRBracket, MakeKeyHandler(GotoBrace, "GotoBrace") },
{ Keys.F3, MakeKeyHandler(CharacterSearch, "CharacterSearch") },
{ Keys.ShiftF3, MakeKeyHandler(CharacterSearchBackward,"CharacterSearchBackward") },
Expand Down Expand Up @@ -120,13 +120,13 @@ private void SetDefaultViBindings()
{ Keys.CtrlC, MakeKeyHandler(CancelLine, "CancelLine") },
{ Keys.CtrlL, MakeKeyHandler(ClearScreen, "ClearScreen") },
{ Keys.CtrlT, MakeKeyHandler(SwapCharacters, "SwapCharacters") },
{ Keys.CtrlU, MakeKeyHandler(BackwardDeleteLine, "BackwardDeleteLine") },
{ Keys.CtrlU, MakeKeyHandler(BackwardDeleteInput, "BackwardDeleteInput") },
{ Keys.CtrlW, MakeKeyHandler(BackwardDeleteWord, "BackwardDeleteWord") },
{ Keys.CtrlY, MakeKeyHandler(Redo, "Redo") },
{ Keys.CtrlZ, MakeKeyHandler(Undo, "Undo") },
{ Keys.CtrlBackspace, MakeKeyHandler(BackwardKillWord, "BackwardKillWord") },
{ Keys.CtrlEnd, MakeKeyHandler(ForwardDeleteLine, "ForwardDeleteLine") },
{ Keys.CtrlHome, MakeKeyHandler(BackwardDeleteLine, "BackwardDeleteLine") },
{ Keys.CtrlEnd, MakeKeyHandler(ForwardDeleteInput, "ForwardDeleteInput") },
{ Keys.CtrlHome, MakeKeyHandler(BackwardDeleteInput, "BackwardDeleteInput") },
{ Keys.CtrlRBracket, MakeKeyHandler(GotoBrace, "GotoBrace") },
{ Keys.F3, MakeKeyHandler(CharacterSearch, "CharacterSearch") },
{ Keys.ShiftF3, MakeKeyHandler(CharacterSearchBackward, "CharacterSearchBackward") },
Expand Down
12 changes: 11 additions & 1 deletion PSReadLine/KillYank.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,21 @@ public static void KillLine(ConsoleKeyInfo? key = null, object arg = null)
/// Clear the input from the start of the input to the cursor. The cleared text is placed
/// in the kill ring.
/// </summary>
public static void BackwardKillLine(ConsoleKeyInfo? key = null, object arg = null)
public static void BackwardKillInput(ConsoleKeyInfo? key = null, object arg = null)
{
_singleton.Kill(0, _singleton._current, true);
}

/// <summary>
/// Clear the input from the start of the current logical line to the cursor. The cleared text is placed
/// in the kill ring.
/// </summary>
public static void BackwardKillLine(ConsoleKeyInfo? key = null, object arg = null)
{
var start = GetBeginningOfLinePos(_singleton._current);
_singleton.Kill(start, _singleton._current, true);
}

/// <summary>
/// Clear the input from the cursor to the end of the current word. If the cursor
/// is between words, the input is cleared from the cursor to the end of the next word.
Expand Down
29 changes: 28 additions & 1 deletion PSReadLine/PSReadLineResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions PSReadLine/PSReadLineResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,17 @@
<data name="BackwardDeleteCharDescription" xml:space="preserve">
<value>Delete the character before the cursor</value>
</data>
<data name="BackwardDeleteInputDescription" xml:space="preserve">
<value>Delete text from the cursor to the start of the input</value>
</data>
<data name="BackwardDeleteLineDescription" xml:space="preserve">
<value>Delete text from the cursor to the start of the line</value>
<value>Delete text from the cursor to the start of the current logical line</value>
</data>
<data name="BackwardKillInputDescription" xml:space="preserve">
<value>Move the text from the cursor to the beginning of the input to the kill ring</value>
</data>
<data name="BackwardKillLineDescription" xml:space="preserve">
<value>Move the text from the cursor to the beginning of the line to the kill ring</value>
<value>Move the text from the start of the current logical line to the cursor to the kill ring</value>
</data>
<data name="BeginningOfHistoryDescription" xml:space="preserve">
<value>Move to the first item in the history</value>
Expand Down Expand Up @@ -180,8 +186,11 @@
<data name="ForwardCharDescription" xml:space="preserve">
<value>Move the cursor forward one character</value>
</data>
<data name="ForwardDeleteInputDescription" xml:space="preserve">
<value>Delete text from the cursor to the end of the input</value>
</data>
<data name="ForwardDeleteLineDescription" xml:space="preserve">
<value>Delete text from the cursor to the end of the line</value>
<value>Delete text from the cursor to the end of the current logical line</value>
</data>
<data name="ShellForwardWordDescription" xml:space="preserve">
<value>Move the cursor to the beginning of the next token or end of line</value>
Expand Down
20 changes: 20 additions & 0 deletions test/BasicEditingTest.VI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,26 @@ public void ViDeleteToEnd()
));
}

[SkippableFact]
public void ViBackwardDeleteLine()
{
TestSetup(KeyMode.Vi);

int continuationPrefixLength = PSConsoleReadLineOptions.DefaultContinuationPrompt.Length;

Test("\"\nsome words\n\"", Keys(

_.DQuote, _.Enter,
" this is a line with some words", _.Enter,
_.DQuote, _.Escape,
"k6W",
CheckThat(() => AssertCursorLeftIs(continuationPrefixLength + 23)),
// delete from first non blank of line
"d0",
CheckThat(() => AssertCursorLeftIs(continuationPrefixLength))
));
}

[SkippableFact]
public void ViDeleteLineToFirstChar()
{
Expand Down
19 changes: 17 additions & 2 deletions test/BasicEditingTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void CancelLine()
}

[SkippableFact]
public void ForwardDeleteLine()
public void ForwardDeleteInput()
{
ConsoleKeyInfo deleteToEnd;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Expand All @@ -98,7 +98,22 @@ public void ForwardDeleteLine()
}

[SkippableFact]
public void BackwardDeleteLine()
public void ForwardDeleteLine()
{
TestSetup(KeyMode.Emacs);

PSConsoleReadLine.SetKeyHandler(new[] { "Shift+Tab" }, PSConsoleReadLine.ForwardDeleteLine, "", "");

Test("\"H\nWorld\"", Keys(
_.DQuote, "Hello", _.Enter,
"World", _.DQuote,
_.Home, _.Home, _.RightArrow, _.RightArrow,
_.Shift_Tab // delete to the end of the current logical line
));
}

[SkippableFact]
public void BackwardDeleteInput()
{
TestSetup(KeyMode.Cmd);

Expand Down
10 changes: 10 additions & 0 deletions test/KillYankTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ public void BackwardKillLine()
{
TestSetup(KeyMode.Emacs);

PSConsoleReadLine.SetKeyHandler(new[] { "Shift+Tab" }, PSConsoleReadLine.BackwardKillLine, "", "");

Test("", Keys("dir", _.Shift_Tab));
}

[SkippableFact]
public void BackwardKillInput()
{
TestSetup(KeyMode.Emacs);

// Kill whole line
// Check killed text by yanking
Test("ls", Keys("dir", _.Ctrl_u, "ls"));
Expand Down