Add --tty-default=/dev/tty and --no-tty-default option (#4352)

Fix #4242.

Use --no-tty-default, if you want fzf to perform a TTY look-up instead of defaulting to /dev/tty.
This commit is contained in:
Junegunn Choi
2025-04-20 11:24:50 +09:00
committed by GitHub
parent e491770f1c
commit 1d761684c5
9 changed files with 53 additions and 27 deletions

View File

@@ -28,7 +28,7 @@ const (
maxInputBuffer = 1024 * 1024
)
const consoleDevice string = "/dev/tty"
const DefaultTtyDevice string = "/dev/tty"
var offsetRegexp = regexp.MustCompile("(.*?)\x00?\x1b\\[([0-9]+);([0-9]+)R")
var offsetRegexpBegin = regexp.MustCompile("^\x1b\\[[0-9]+;[0-9]+R")
@@ -146,8 +146,8 @@ type LightWindow struct {
wrapSignWidth int
}
func NewLightRenderer(ttyin *os.File, theme *ColorTheme, forceBlack bool, mouse bool, tabstop int, clearOnExit bool, fullscreen bool, maxHeightFunc func(int) int) (Renderer, error) {
out, err := openTtyOut()
func NewLightRenderer(ttyDefault string, ttyin *os.File, theme *ColorTheme, forceBlack bool, mouse bool, tabstop int, clearOnExit bool, fullscreen bool, maxHeightFunc func(int) int) (Renderer, error) {
out, err := openTtyOut(ttyDefault)
if err != nil {
out = os.Stderr
}
@@ -271,7 +271,7 @@ func (r *LightRenderer) getBytesInternal(buffer []byte, nonblock bool) ([]byte,
c, ok := r.getch(nonblock)
if !nonblock && !ok {
r.Close()
return nil, errors.New("failed to read " + consoleDevice)
return nil, errors.New("failed to read " + DefaultTtyDevice)
}
retries := 0

View File

@@ -42,26 +42,35 @@ func (r *LightRenderer) closePlatform() {
r.ttyout.Close()
}
func openTty(mode int) (*os.File, error) {
in, err := os.OpenFile(consoleDevice, mode, 0)
if err != nil {
func openTty(ttyDefault string, mode int) (*os.File, error) {
var in *os.File
var err error
if len(ttyDefault) > 0 {
in, err = os.OpenFile(ttyDefault, mode, 0)
}
if in == nil || err != nil || ttyDefault != DefaultTtyDevice && !util.IsTty(in) {
tty := ttyname()
if len(tty) > 0 {
if in, err := os.OpenFile(tty, mode, 0); err == nil {
return in, nil
}
}
return nil, errors.New("failed to open " + consoleDevice)
if ttyDefault != DefaultTtyDevice {
if in, err = os.OpenFile(DefaultTtyDevice, mode, 0); err == nil {
return in, nil
}
}
return nil, errors.New("failed to open " + DefaultTtyDevice)
}
return in, nil
}
func openTtyIn() (*os.File, error) {
return openTty(syscall.O_RDONLY)
func openTtyIn(ttyDefault string) (*os.File, error) {
return openTty(ttyDefault, syscall.O_RDONLY)
}
func openTtyOut() (*os.File, error) {
return openTty(syscall.O_WRONLY)
func openTtyOut(ttyDefault string) (*os.File, error) {
return openTty(ttyDefault, syscall.O_WRONLY)
}
func (r *LightRenderer) setupTerminal() {

View File

@@ -76,12 +76,12 @@ func (r *LightRenderer) closePlatform() {
windows.SetConsoleMode(windows.Handle(r.inHandle), r.origStateInput)
}
func openTtyIn() (*os.File, error) {
func openTtyIn(ttyDefault string) (*os.File, error) {
// not used
return nil, nil
}
func openTtyOut() (*os.File, error) {
func openTtyOut(ttyDefault string) (*os.File, error) {
return os.Stderr, nil
}

View File

@@ -44,11 +44,11 @@ func ttyname() string {
}
// TtyIn returns terminal device to read user input
func TtyIn() (*os.File, error) {
return openTtyIn()
func TtyIn(ttyDefault string) (*os.File, error) {
return openTtyIn(ttyDefault)
}
// TtyIn returns terminal device to write to
func TtyOut() (*os.File, error) {
return openTtyOut()
func TtyOut(ttyDefault string) (*os.File, error) {
return openTtyOut(ttyDefault)
}

View File

@@ -11,11 +11,11 @@ func ttyname() string {
}
// TtyIn on Windows returns os.Stdin
func TtyIn() (*os.File, error) {
func TtyIn(ttyDefault string) (*os.File, error) {
return os.Stdin, nil
}
// TtyOut on Windows returns nil
func TtyOut() (*os.File, error) {
func TtyOut(ttyDefault string) (*os.File, error) {
return nil, nil
}