From 9b991dd831b8a478f9fc99a0b39b492b4e25a3c0 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Tue, 16 Dec 2025 08:15:40 -0800 Subject: [PATCH] x/term: handle delete key Fixes golang/go#76826 Change-Id: I80dc9468c2cc716dab10a8e165ca5f72817ef4b9 Reviewed-on: https://go-review.googlesource.com/c/term/+/730440 Auto-Submit: Michael Knyszek Reviewed-by: David Chase Reviewed-by: Michael Knyszek LUCI-TryBot-Result: Go LUCI --- terminal.go | 7 ++++++- terminal_test.go | 27 ++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/terminal.go b/terminal.go index 9255449..5fdfff0 100644 --- a/terminal.go +++ b/terminal.go @@ -160,6 +160,7 @@ const ( keyEnd keyDeleteWord keyDeleteLine + keyDelete keyClearScreen keyPasteStart keyPasteEnd @@ -228,6 +229,10 @@ func bytesToKey(b []byte, pasteActive bool) (rune, []byte) { } } + if !pasteActive && len(b) >= 4 && b[0] == keyEscape && b[1] == '[' && b[2] == '3' && b[3] == '~' { + return keyDelete, b[4:] + } + if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' { switch b[5] { case 'C': @@ -590,7 +595,7 @@ func (t *Terminal) handleKey(key rune) (line string, ok bool) { } t.line = t.line[:t.pos] t.moveCursorToPos(t.pos) - case keyCtrlD: + case keyCtrlD, keyDelete: // Erase the character under the current position. // The EOF case when the line is empty is handled in // readLine(). diff --git a/terminal_test.go b/terminal_test.go index 5d35cc5..45aeffa 100644 --- a/terminal_test.go +++ b/terminal_test.go @@ -238,6 +238,31 @@ var keyPressTests = []struct { in: "a\003\r", err: io.EOF, }, + { + // Delete at EOL: nothing + in: "abc\x1b[3~\r", + line: "abc", + }, + { + // Delete in empty string: nothing + in: "\x1b[3~\r", + line: "", + }, + { + // Move left, delete: delete 'c' + in: "abc\x1b[D\x1b[3~\r", + line: "ab", + }, + { + // Home, delete: delete 'a' + in: "abc\x1b[H\x1b[3~\r", + line: "bc", + }, + { + // Home, delete twice: delete 'a' and 'b' + in: "abc\x1b[H\x1b[3~\x1b[3~\r", + line: "c", + }, } func TestKeyPresses(t *testing.T) { @@ -387,7 +412,7 @@ func TestReadPasswordLineEnd(t *testing.T) { input string want string } - var tests = []testType{ + tests := []testType{ {"\r\n", ""}, {"test\r\n", "test"}, {"test\r", "test"},