treat `Ctrl+D` + EmptyLine = EOF, `Ctrl+C` = ErrInterrupt

This commit is contained in:
Cheney 2015-11-19 11:55:07 +08:00
parent 9364259fb1
commit 7a18498f5b
2 changed files with 30 additions and 10 deletions

View File

@ -1,6 +1,7 @@
package readline
import (
"errors"
"fmt"
"io"
"os"
@ -8,11 +9,16 @@ import (
"golang.org/x/crypto/ssh/terminal"
)
var (
ErrInterrupt = errors.New("Interrupt")
)
type Operation struct {
cfg *Config
t *Terminal
buf *RuneBuffer
outchan chan []rune
errchan chan error
w io.Writer
*opHistory
@ -55,6 +61,7 @@ func NewOperation(t *Terminal, cfg *Config) *Operation {
t: t,
buf: NewRuneBuffer(t, cfg.Prompt),
outchan: make(chan []rune),
errchan: make(chan error),
}
op.SetHistoryPath(cfg.HistoryFile)
op.opVim = newVimMode(op)
@ -141,10 +148,6 @@ func (o *Operation) ioloop() {
o.buf.MoveToLineStart()
case CharLineEnd:
o.buf.MoveToLineEnd()
case CharDelete:
if !o.buf.Delete() {
o.t.Bell()
}
case CharBackspace, CharCtrlH:
if o.IsSearchMode() {
o.SearchBackspace()
@ -190,6 +193,18 @@ func (o *Operation) ioloop() {
} else {
o.t.Bell()
}
case CharDelete:
if o.buf.Len() > 0 || !o.IsNormalMode() {
o.t.KickRead()
if !o.buf.Delete() {
o.t.Bell()
}
break
}
// treat as EOF
o.buf.WriteString("^D\n")
o.errchan <- io.EOF
case CharInterrupt:
if o.IsSearchMode() {
o.t.KickRead()
@ -205,7 +220,7 @@ func (o *Operation) ioloop() {
o.buf.MoveToLineEnd()
o.buf.Refresh(nil)
o.buf.WriteString("^C\n")
o.outchan <- nil
o.errchan <- ErrInterrupt
default:
if o.IsSearchMode() {
o.SearchChar(r)
@ -259,11 +274,12 @@ func (o *Operation) Runes() ([]rune, error) {
o.buf.Refresh(nil) // print prompt
o.t.KickRead()
r := <-o.outchan
if r == nil {
return nil, io.EOF
select {
case r := <-o.outchan:
return r, nil
case err := <-o.errchan:
return nil, err
}
return r, nil
}
func (o *Operation) Password(prompt string) ([]byte, error) {
@ -302,3 +318,7 @@ func (o *Operation) SetHistoryPath(path string) {
o.cfg.HistoryFile = path
o.opHistory = newOpHistory(o.cfg)
}
func (o *Operation) IsNormalMode() bool {
return !o.IsInCompleteMode() && !o.IsSearchMode()
}

View File

@ -129,7 +129,7 @@ func (t *Terminal) ioloop() {
break
}
isEscape = true
case CharInterrupt, CharEnter, CharCtrlJ:
case CharInterrupt, CharEnter, CharCtrlJ, CharDelete:
expectNextChar = false
fallthrough
default: