diff --git a/terminal.go b/terminal.go index d1b4fca..2ffb97b 100644 --- a/terminal.go +++ b/terminal.go @@ -113,6 +113,7 @@ func NewTerminal(c io.ReadWriter, prompt string) *Terminal { } const ( + keyCtrlC = 3 keyCtrlD = 4 keyCtrlU = 21 keyEnter = '\r' @@ -151,8 +152,12 @@ func bytesToKey(b []byte, pasteActive bool) (rune, []byte) { switch b[0] { case 1: // ^A return keyHome, b[1:] + case 2: // ^B + return keyLeft, b[1:] case 5: // ^E return keyEnd, b[1:] + case 6: // ^F + return keyRight, b[1:] case 8: // ^H return keyBackspace, b[1:] case 11: // ^K @@ -738,6 +743,9 @@ func (t *Terminal) readLine() (line string, err error) { return "", io.EOF } } + if key == keyCtrlC { + return "", io.EOF + } if key == keyPasteStart { t.pasteActive = true if len(t.line) == 0 { diff --git a/terminal_test.go b/terminal_test.go index 2a2facc..c99638d 100644 --- a/terminal_test.go +++ b/terminal_test.go @@ -81,6 +81,14 @@ var keyPressTests = []struct { in: "a\x1b[Db\r", // left line: "ba", }, + { + in: "a\006b\r", // ^F + line: "ab", + }, + { + in: "a\002b\r", // ^B + line: "ba", + }, { in: "a\177b\r", // backspace line: "b", @@ -208,6 +216,16 @@ var keyPressTests = []struct { line: "a", err: ErrPasteIndicator, }, + { + // Ctrl-C terminates readline + in: "\003", + err: io.EOF, + }, + { + // Ctrl-C at the end of line also terminates readline + in: "a\003\r", + err: io.EOF, + }, } func TestKeyPresses(t *testing.T) {