Do not 'become' inside a tmux popup

fzf --tmux center --bind 'enter:become:vim {}'
This commit is contained in:
Junegunn Choi 2024-05-13 23:33:04 +09:00
parent c24256cba3
commit 04dfb14e32
4 changed files with 42 additions and 3 deletions

View File

@ -67,9 +67,9 @@ const (
) )
const ( const (
ExitCancel = -1
ExitOk = 0 ExitOk = 0
ExitNoMatch = 1 ExitNoMatch = 1
ExitError = 2 ExitError = 2
ExitBecome = 126
ExitInterrupt = 130 ExitInterrupt = 130
) )

View File

@ -381,6 +381,7 @@ type Options struct {
Input chan string Input chan string
Output chan string Output chan string
Tmux *tmuxOptions Tmux *tmuxOptions
TmuxScript string
Bash bool Bash bool
Zsh bool Zsh bool
Fish bool Fish bool
@ -1882,6 +1883,10 @@ func parseOptions(opts *Options, allArgs []string) error {
} }
case "--no-tmux": case "--no-tmux":
opts.Tmux = nil opts.Tmux = nil
case "--tmux-script":
if opts.TmuxScript, err = nextString(allArgs, &i, ""); err != nil {
return err
}
case "-x", "--extended": case "-x", "--extended":
opts.Extended = true opts.Extended = true
case "-e", "--exact": case "-e", "--exact":

View File

@ -312,6 +312,7 @@ type Terminal struct {
forcePreview bool forcePreview bool
clickHeaderLine int clickHeaderLine int
clickHeaderColumn int clickHeaderColumn int
tmuxScript string
} }
type selectedItem struct { type selectedItem struct {
@ -351,6 +352,7 @@ const (
reqPreviewDisplay reqPreviewDisplay
reqPreviewRefresh reqPreviewRefresh
reqPreviewDelayed reqPreviewDelayed
reqBecome
reqQuit reqQuit
reqFatal reqFatal
) )
@ -782,6 +784,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
jumpLabels: opts.JumpLabels, jumpLabels: opts.JumpLabels,
printer: opts.Printer, printer: opts.Printer,
printsep: opts.PrintSep, printsep: opts.PrintSep,
tmuxScript: opts.TmuxScript,
merger: EmptyMerger(0), merger: EmptyMerger(0),
selected: make(map[int32]selectedItem), selected: make(map[int32]selectedItem),
reqBox: util.NewEventBox(), reqBox: util.NewEventBox(),
@ -3299,6 +3302,9 @@ func (t *Terminal) Loop() error {
return ExitOk return ExitOk
}) })
return return
case reqBecome:
exit(func() int { return ExitBecome })
return
case reqQuit: case reqQuit:
exit(func() int { return ExitInterrupt }) exit(func() int { return ExitInterrupt })
return return
@ -3473,8 +3479,15 @@ func (t *Terminal) Loop() error {
if t.history != nil { if t.history != nil {
t.history.append(string(t.input)) t.history.append(string(t.input))
} }
if len(t.tmuxScript) > 0 {
data := strings.Join(append([]string{command}, t.environ()...), "\x00")
os.WriteFile(t.tmuxScript, []byte(data), 0600)
req(reqBecome)
} else {
t.executor.Become(t.ttyin, t.environ(), command) t.executor.Become(t.ttyin, t.environ(), command)
} }
}
case actExecute, actExecuteSilent: case actExecute, actExecuteSilent:
t.executeCommand(a.a, false, a.t == actExecuteSilent, false, false) t.executeCommand(a.a, false, a.t == actExecuteSilent, false, false)
case actExecuteMulti: case actExecuteMulti:

View File

@ -2,6 +2,7 @@ package fzf
import ( import (
"bufio" "bufio"
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -45,6 +46,7 @@ func runTmux(args []string, opts *Options) (int, error) {
// %q formatting escapes $'foo\nbar' to "foo\nbar" // %q formatting escapes $'foo\nbar' to "foo\nbar"
argStr += " " + escapeSingleQuote(arg) argStr += " " + escapeSingleQuote(arg)
} }
argStr += ` --tmux-script "$0"`
// Build command // Build command
var command string var command string
@ -141,7 +143,26 @@ func runTmux(args []string, opts *Options) (int, error) {
cmd := exec.Command("tmux", tmuxArgs...) cmd := exec.Command("tmux", tmuxArgs...)
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
if exitError, ok := err.(*exec.ExitError); ok { if exitError, ok := err.(*exec.ExitError); ok {
return exitError.ExitCode(), err code := exitError.ExitCode()
if code == ExitBecome {
data, err := os.ReadFile(temp)
if err != nil {
return ExitError, err
}
elems := strings.Split(string(data), "\x00")
if len(elems) < 1 {
return ExitError, errors.New("invalid become command")
}
command := elems[0]
env := []string{}
if len(elems) > 1 {
env = elems[1:]
}
os.Remove(temp)
executor := util.NewExecutor(opts.WithShell)
executor.Become(tui.TtyIn(), env, command)
}
return code, err
} }
} }