diff --git a/vendor/github.com/chzyer/readline/example/readline-demo/readline-demo.go b/vendor/github.com/chzyer/readline/example/readline-demo/readline-demo.go index e6c0a53..2b1daf7 100644 --- a/vendor/github.com/chzyer/readline/example/readline-demo/readline-demo.go +++ b/vendor/github.com/chzyer/readline/example/readline-demo/readline-demo.go @@ -61,6 +61,15 @@ var completer = readline.NewPrefixCompleter( readline.PcItem("sleep"), ) +func filterInput(r rune) (rune, bool) { + switch r { + // block CtrlZ feature + case readline.CharCtrlZ: + return r, false + } + return r, true +} + func main() { l, err := readline.NewEx(&readline.Config{ Prompt: "\033[31m»\033[0m ", @@ -69,7 +78,8 @@ func main() { InterruptPrompt: "^C", EOFPrompt: "exit", - HistorySearchFold: true, + HistorySearchFold: true, + FuncFilterInputRune: filterInput, }) if err != nil { panic(err) @@ -127,12 +137,11 @@ func main() { println("you set:", strconv.Quote(string(pswd))) } case strings.HasPrefix(line, "setprompt"): - prompt := line[10:] - if prompt == "" { + if len(line) <= 10 { log.Println("setprompt ") break } - l.SetPrompt(prompt) + l.SetPrompt(line[10:]) case strings.HasPrefix(line, "say"): line := strings.TrimSpace(line[3:]) if len(line) == 0 { diff --git a/vendor/github.com/chzyer/readline/operation.go b/vendor/github.com/chzyer/readline/operation.go index 3347a5d..497e6c6 100644 --- a/vendor/github.com/chzyer/readline/operation.go +++ b/vendor/github.com/chzyer/readline/operation.go @@ -32,6 +32,10 @@ type Operation struct { *opVim } +func (o *Operation) SetBuffer(what string) { + o.buf.Set([]rune(what)) +} + type wrapWriter struct { r *Operation t *Terminal @@ -92,6 +96,15 @@ func (o *Operation) ioloop() { keepInSearchMode := false keepInCompleteMode := false r := o.t.ReadRune() + if o.cfg.FuncFilterInputRune != nil { + var process bool + r, process = o.cfg.FuncFilterInputRune(r) + if !process { + o.buf.Refresh(nil) // to refresh the line + continue // ignore this rune + } + } + if r == 0 { // io.EOF if o.buf.Len() == 0 { o.buf.Clean() diff --git a/vendor/github.com/chzyer/readline/readline.go b/vendor/github.com/chzyer/readline/readline.go index 1e232fb..b0242f7 100644 --- a/vendor/github.com/chzyer/readline/readline.go +++ b/vendor/github.com/chzyer/readline/readline.go @@ -63,6 +63,10 @@ type Config struct { // it use in IM usually. UniqueEditLine bool + // filter input runes (may be used to disable CtrlZ or for translating some keys to different actions) + // -> output = new (translated) rune and true/false if continue with processing this one + FuncFilterInputRune func(rune) (rune, bool) + // force use interactive even stdout is not a tty FuncIsTerminal func() bool FuncMakeRaw func() error @@ -238,6 +242,11 @@ func (i *Instance) Readline() (string, error) { return i.Operation.String() } +func (i *Instance) ReadlineWithDefault(what string) (string, error) { + i.Operation.SetBuffer(what) + return i.Operation.String() +} + func (i *Instance) SaveHistory(content string) error { return i.Operation.SaveHistory(content) } diff --git a/vendor/github.com/chzyer/readline/term.go b/vendor/github.com/chzyer/readline/term.go index 87ef8f7..133993c 100644 --- a/vendor/github.com/chzyer/readline/term.go +++ b/vendor/github.com/chzyer/readline/term.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd +// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd solaris // Package terminal provides support functions for dealing with terminals, as // commonly found on UNIX systems. @@ -19,19 +19,17 @@ package readline import ( "io" "syscall" - "unsafe" ) // State contains the state of a terminal. type State struct { - termios syscall.Termios + termios Termios } // IsTerminal returns true if the given file descriptor is a terminal. func IsTerminal(fd int) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 + _, err := getTermios(fd) + return err == nil } // MakeRaw put the terminal connected to the given file descriptor into raw @@ -39,8 +37,11 @@ func IsTerminal(fd int) bool { // restored. func MakeRaw(fd int) (*State, error) { var oldState State - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { + + if termios, err := getTermios(fd); err != nil { return nil, err + } else { + oldState.termios = *termios } newState := oldState.termios @@ -52,47 +53,35 @@ func MakeRaw(fd int) (*State, error) { newState.Cflag &^= syscall.CSIZE | syscall.PARENB newState.Cflag |= syscall.CS8 - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { - return nil, err - } + newState.Cc[syscall.VMIN] = 1 + newState.Cc[syscall.VTIME] = 0 - return &oldState, nil + return &oldState, setTermios(fd, &newState) } // GetState returns the current state of a terminal which may be useful to // restore the terminal after a signal. func GetState(fd int) (*State, error) { - var oldState State - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { + termios, err := getTermios(fd) + if err != nil { return nil, err } - return &oldState, nil + return &State{termios: *termios}, nil } // Restore restores the terminal connected to the given file descriptor to a // previous state. func restoreTerm(fd int, state *State) error { - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0) - return err -} - -// GetSize returns the dimensions of the given terminal. -func GetSize(fd int) (width, height int, err error) { - var dimensions [4]uint16 - - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 { - return -1, -1, err - } - return int(dimensions[1]), int(dimensions[0]), nil + return setTermios(fd, &state.termios) } // ReadPassword reads a line of input from a terminal without local echo. This // is commonly used for inputting passwords and other sensitive data. The slice // returned does not include the \n. func ReadPassword(fd int) ([]byte, error) { - var oldState syscall.Termios - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 { + oldState, err := getTermios(fd) + if err != nil { return nil, err } @@ -100,12 +89,12 @@ func ReadPassword(fd int) ([]byte, error) { newState.Lflag &^= syscall.ECHO newState.Lflag |= syscall.ICANON | syscall.ISIG newState.Iflag |= syscall.ICRNL - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { + if err := setTermios(fd, newState); err != nil { return nil, err } defer func() { - syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0) + setTermios(fd, oldState) }() var buf [16]byte diff --git a/vendor/github.com/chzyer/readline/term_bsd.go b/vendor/github.com/chzyer/readline/term_bsd.go index 69682cd..68b56ea 100644 --- a/vendor/github.com/chzyer/readline/term_bsd.go +++ b/vendor/github.com/chzyer/readline/term_bsd.go @@ -6,7 +6,24 @@ package readline -import "syscall" +import ( + "syscall" + "unsafe" +) -const ioctlReadTermios = syscall.TIOCGETA -const ioctlWriteTermios = syscall.TIOCSETA +func getTermios(fd int) (*Termios, error) { + termios := new(Termios) + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCGETA, uintptr(unsafe.Pointer(termios)), 0, 0, 0) + if err != 0 { + return nil, err + } + return termios, nil +} + +func setTermios(fd int, termios *Termios) error { + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCSETA, uintptr(unsafe.Pointer(termios)), 0, 0, 0) + if err != 0 { + return err + } + return nil +} diff --git a/vendor/github.com/chzyer/readline/term_linux.go b/vendor/github.com/chzyer/readline/term_linux.go index 8918008..e3392b4 100644 --- a/vendor/github.com/chzyer/readline/term_linux.go +++ b/vendor/github.com/chzyer/readline/term_linux.go @@ -4,8 +4,30 @@ package readline +import ( + "syscall" + "unsafe" +) + // These constants are declared here, rather than importing // them from the syscall package as some syscall packages, even // on linux, for example gccgo, do not declare them. const ioctlReadTermios = 0x5401 // syscall.TCGETS const ioctlWriteTermios = 0x5402 // syscall.TCSETS + +func getTermios(fd int) (*Termios, error) { + termios := new(Termios) + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(termios)), 0, 0, 0) + if err != 0 { + return nil, err + } + return termios, nil +} + +func setTermios(fd int, termios *Termios) error { + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(termios)), 0, 0, 0) + if err != 0 { + return err + } + return nil +} diff --git a/vendor/github.com/chzyer/readline/term_solaris.go b/vendor/github.com/chzyer/readline/term_solaris.go new file mode 100644 index 0000000..4c27273 --- /dev/null +++ b/vendor/github.com/chzyer/readline/term_solaris.go @@ -0,0 +1,32 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build solaris + +package readline + +import "golang.org/x/sys/unix" + +// GetSize returns the dimensions of the given terminal. +func GetSize(fd int) (int, int, error) { + ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) + if err != nil { + return 0, 0, err + } + return int(ws.Col), int(ws.Row), nil +} + +type Termios unix.Termios + +func getTermios(fd int) (*Termios, error) { + termios, err := unix.IoctlGetTermios(fd, unix.TCGETS) + if err != nil { + return nil, err + } + return (*Termios)(termios), nil +} + +func setTermios(fd int, termios *Termios) error { + return unix.IoctlSetTermios(fd, unix.TCSETSF, (*unix.Termios)(termios)) +} diff --git a/vendor/github.com/chzyer/readline/term_unix.go b/vendor/github.com/chzyer/readline/term_unix.go new file mode 100644 index 0000000..d3ea242 --- /dev/null +++ b/vendor/github.com/chzyer/readline/term_unix.go @@ -0,0 +1,24 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd + +package readline + +import ( + "syscall" + "unsafe" +) + +type Termios syscall.Termios + +// GetSize returns the dimensions of the given terminal. +func GetSize(fd int) (int, int, error) { + var dimensions [4]uint16 + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0) + if err != 0 { + return 0, 0, err + } + return int(dimensions[1]), int(dimensions[0]), nil +} diff --git a/vendor/github.com/chzyer/readline/terminal.go b/vendor/github.com/chzyer/readline/terminal.go index b3d1caf..8014712 100644 --- a/vendor/github.com/chzyer/readline/terminal.go +++ b/vendor/github.com/chzyer/readline/terminal.go @@ -10,6 +10,7 @@ import ( ) type Terminal struct { + m sync.Mutex cfg *Config outchan chan rune closed int32 @@ -121,7 +122,7 @@ func (t *Terminal) ioloop() { expectNextChar bool ) - buf := bufio.NewReader(t.cfg.Stdin) + buf := bufio.NewReader(t.getStdin()) for { if !expectNextChar { atomic.StoreInt32(&t.isReading, 0) @@ -206,10 +207,26 @@ func (t *Terminal) Close() error { return t.ExitRawMode() } +func (t *Terminal) GetConfig() *Config { + t.m.Lock() + cfg := *t.cfg + t.m.Unlock() + return &cfg +} + +func (t *Terminal) getStdin() io.Reader { + t.m.Lock() + r := t.cfg.Stdin + t.m.Unlock() + return r +} + func (t *Terminal) SetConfig(c *Config) error { if err := c.Init(); err != nil { return err } + t.m.Lock() t.cfg = c + t.m.Unlock() return nil } diff --git a/vendor/github.com/chzyer/readline/utils.go b/vendor/github.com/chzyer/readline/utils.go index 96518f1..670736b 100644 --- a/vendor/github.com/chzyer/readline/utils.go +++ b/vendor/github.com/chzyer/readline/utils.go @@ -82,7 +82,9 @@ func Restore(fd int, state *State) error { if err != nil { // errno 0 means everything is ok :) if err.Error() == "errno 0" { - err = nil + return nil + } else { + return err } } return nil diff --git a/vendor/github.com/chzyer/readline/utils_unix.go b/vendor/github.com/chzyer/readline/utils_unix.go index 39c32a1..f88dac9 100644 --- a/vendor/github.com/chzyer/readline/utils_unix.go +++ b/vendor/github.com/chzyer/readline/utils_unix.go @@ -1,4 +1,4 @@ -// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd +// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd solaris package readline @@ -8,7 +8,6 @@ import ( "os/signal" "sync" "syscall" - "unsafe" ) type winsize struct { @@ -30,17 +29,11 @@ func SuspendMe() { // get width of the terminal func getWidth(stdoutFd int) int { - ws := &winsize{} - retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL, - uintptr(stdoutFd), - uintptr(syscall.TIOCGWINSZ), - uintptr(unsafe.Pointer(ws))) - - if int(retCode) == -1 { - _ = errno + cols, _, err := GetSize(stdoutFd) + if err != nil { return -1 } - return int(ws.Col) + return cols } func GetScreenWidth() int { diff --git a/vendor/manifest b/vendor/manifest index 371357a..5764b47 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -23,7 +23,7 @@ "importpath": "github.com/chzyer/readline", "repository": "https://github.com/special/readline", "vcs": "git", - "revision": "435ac8270991572ea8df6de2add266b6d818d9f3", + "revision": "e06700a8ff17afd011891f52e148da8dcf84ee2f", "branch": "refresh-race", "notests": true },