Make fzf immediately quit when failed to read /dev/tty

Close #798
This commit is contained in:
Junegunn Choi 2017-01-11 02:12:32 +09:00
parent 0c127cfdc1
commit 996dcb14a3
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
4 changed files with 32 additions and 19 deletions

View File

@ -111,8 +111,10 @@ func (r *LightRenderer) defaultTheme() *ColorTheme {
return Default16
}
func stty(cmd string) string {
out, err := util.ExecCommand("stty " + cmd + " < /dev/tty").Output()
func (r *LightRenderer) stty(cmd string) string {
proc := util.ExecCommand("stty " + cmd)
proc.Stdin = r.ttyin
out, err := proc.Output()
if err != nil {
// Not sure how to handle this
panic("stty " + cmd + ": " + err.Error())
@ -164,8 +166,8 @@ func (r *LightRenderer) Init() {
}
r.escDelay = delay
r.ostty = stty("-g")
stty("raw")
r.ostty = r.stty("-g")
r.stty("raw")
r.updateTerminalSize()
initTheme(r.theme, r.defaultTheme(), r.forceBlack)
@ -210,7 +212,7 @@ func (r *LightRenderer) origin() {
}
func (r *LightRenderer) updateTerminalSize() {
sizes := strings.Split(stty("size"), " ")
sizes := strings.Split(r.stty("size"), " ")
if len(sizes) < 2 {
r.width = defaultWidth
r.height = r.maxHeightFunc(defaultHeight)
@ -220,14 +222,14 @@ func (r *LightRenderer) updateTerminalSize() {
}
}
func (r *LightRenderer) getch(nonblock bool) int {
func (r *LightRenderer) getch(nonblock bool) (int, bool) {
b := make([]byte, 1)
util.SetNonblock(r.ttyin, nonblock)
_, err := r.ttyin.Read(b)
if err != nil {
return -1
return 0, false
}
return int(b[0])
return int(b[0]), true
}
func (r *LightRenderer) getBytes() []byte {
@ -235,7 +237,11 @@ func (r *LightRenderer) getBytes() []byte {
}
func (r *LightRenderer) getBytesInternal(buffer []byte) []byte {
c := r.getch(false)
c, ok := r.getch(false)
if !ok {
r.Close()
errorExit()
}
retries := 0
if c == ESC {
@ -244,8 +250,8 @@ func (r *LightRenderer) getBytesInternal(buffer []byte) []byte {
buffer = append(buffer, byte(c))
for {
c = r.getch(true)
if c == -1 {
c, ok = r.getch(true)
if !ok {
if retries > 0 {
retries--
time.Sleep(escPollInterval * time.Millisecond)
@ -479,13 +485,13 @@ func (r *LightRenderer) mouseSequence(sz *int) Event {
}
func (r *LightRenderer) Pause() {
stty(fmt.Sprintf("%q", r.ostty))
r.stty(fmt.Sprintf("%q", r.ostty))
r.csi("?1049h")
r.flush()
}
func (r *LightRenderer) Resume() bool {
stty("raw")
r.stty("raw")
r.csi("?1049l")
r.flush()
// Should redraw
@ -518,7 +524,7 @@ func (r *LightRenderer) Close() {
r.csi("A")
}
r.flush()
stty(fmt.Sprintf("%q", r.ostty))
r.stty(fmt.Sprintf("%q", r.ostty))
}
func (r *LightRenderer) MaxX() int {

View File

@ -110,12 +110,12 @@ func (r *FullscreenRenderer) Init() {
tty := C.c_tty()
if tty == nil {
fmt.Println("Failed to open /dev/tty")
os.Exit(2)
errorExit()
}
_screen = C.c_newterm(tty)
if _screen == nil {
fmt.Println("Invalid $TERM: " + os.Getenv("TERM"))
os.Exit(2)
errorExit()
}
C.set_term(_screen)
if r.mouse {
@ -375,7 +375,9 @@ func (r *FullscreenRenderer) GetChar() Event {
c := C.getch()
switch c {
case C.ERR:
return Event{Invalid, 0, nil}
// Unexpected error from blocking read
r.Close()
errorExit()
case C.KEY_UP:
return Event{Up, 0, nil}
case C.KEY_DOWN:

View File

@ -124,11 +124,11 @@ func (r *FullscreenRenderer) initScreen() {
s, e := tcell.NewScreen()
if e != nil {
fmt.Fprintf(os.Stderr, "%v\n", e)
os.Exit(2)
errorExit()
}
if e = s.Init(); e != nil {
fmt.Fprintf(os.Stderr, "%v\n", e)
os.Exit(2)
errorExit()
}
if r.mouse {
s.EnableMouse()

View File

@ -1,6 +1,7 @@
package tui
import (
"os"
"strconv"
"time"
)
@ -275,6 +276,10 @@ func EmptyTheme() *ColorTheme {
Border: colUndefined}
}
func errorExit() {
os.Exit(2)
}
func init() {
Default16 = &ColorTheme{
Fg: colDefault,