From 1e409caaf3dcb4d28171bc08fc5dcd7e2ac22b84 Mon Sep 17 00:00:00 2001 From: chzyer <0@0xdf.com> Date: Fri, 25 Mar 2016 17:08:13 +0800 Subject: [PATCH] return remain line if interrupt. --- example/readline-demo/readline-demo.go | 11 +++++++++-- operation.go | 24 +++++++++++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/example/readline-demo/readline-demo.go b/example/readline-demo/readline-demo.go index 23b1ffc..eeb3605 100644 --- a/example/readline-demo/readline-demo.go +++ b/example/readline-demo/readline-demo.go @@ -47,7 +47,7 @@ func main() { Prompt: "\033[31m»\033[0m ", HistoryFile: "/tmp/readline.tmp", AutoComplete: completer, - InterruptPrompt: "\nInterrupt, Press Ctrl+D to exit", + InterruptPrompt: "^C", EOFPrompt: "exit", }) if err != nil { @@ -65,9 +65,16 @@ func main() { log.SetOutput(l.Stderr()) for { line, err := l.Readline() - if err == io.EOF { + if err == readline.ErrInterrupt { + if len(line) == 0 { + break + } else { + continue + } + } else if err == io.EOF { break } + line = strings.TrimSpace(line) switch { case strings.HasPrefix(line, "mode "): diff --git a/operation.go b/operation.go index c896fda..985103c 100644 --- a/operation.go +++ b/operation.go @@ -9,6 +9,14 @@ var ( ErrInterrupt = errors.New("Interrupt") ) +type InterruptError struct { + Line []rune +} + +func (*InterruptError) Error() string { + return "Interrupted" +} + type Operation struct { cfg *Config t *Terminal @@ -248,11 +256,13 @@ func (o *Operation) ioloop() { } o.buf.MoveToLineEnd() o.buf.Refresh(nil) - o.buf.WriteString(o.cfg.InterruptPrompt + "\n") - o.buf.Reset() + hint := o.cfg.InterruptPrompt + "\n" + o.buf.WriteString(hint) + remain := o.buf.Reset() + remain = remain[:len(remain)-len([]rune(hint))] isUpdateHistory = false o.history.Revert() - o.errchan <- ErrInterrupt + o.errchan <- &InterruptError{remain} default: if o.IsSearchMode() { o.SearchChar(r) @@ -302,10 +312,7 @@ func (o *Operation) Stdout() io.Writer { func (o *Operation) String() (string, error) { r, err := o.Runes() - if err != nil { - return "", err - } - return string(r), nil + return string(r), err } func (o *Operation) Runes() ([]rune, error) { @@ -321,6 +328,9 @@ func (o *Operation) Runes() ([]rune, error) { case r := <-o.outchan: return r, nil case err := <-o.errchan: + if e, ok := err.(*InterruptError); ok { + return e.Line, ErrInterrupt + } return nil, err } }