summaryrefslogtreecommitdiffstats
path: root/src/terminal.go
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2024-04-27 18:36:37 +0900
committerGitHub <noreply@github.com>2024-04-27 18:36:37 +0900
commita4391aeedd4fec1865d2d646711f58d04058531b (patch)
tree73a6862010c323f380a3105f929b41a39c7a3753 /src/terminal.go
parentb86a967ee217f4c820249701218a17eaad2737ae (diff)
Add --with-shell for shelling out with different command and flags (#3746)
Close #3732
Diffstat (limited to 'src/terminal.go')
-rw-r--r--src/terminal.go53
1 files changed, 25 insertions, 28 deletions
diff --git a/src/terminal.go b/src/terminal.go
index 25f30150..8d114e1b 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -7,7 +7,6 @@ import (
"io"
"math"
"os"
- "os/exec"
"os/signal"
"regexp"
"sort"
@@ -245,6 +244,7 @@ type Terminal struct {
listenUnsafe bool
borderShape tui.BorderShape
cleanExit bool
+ executor *util.Executor
paused bool
border tui.Window
window tui.Window
@@ -640,7 +640,7 @@ func evaluateHeight(opts *Options, termHeight int) int {
}
// NewTerminal returns new Terminal object
-func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
+func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor) *Terminal {
input := trimQuery(opts.Query)
var delay time.Duration
if opts.Tac {
@@ -736,6 +736,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
previewLabel: nil,
previewLabelOpts: opts.PreviewLabel,
cleanExit: opts.ClearOnExit,
+ executor: executor,
paused: opts.Phony,
cycle: opts.Cycle,
headerVisible: true,
@@ -2522,6 +2523,7 @@ type replacePlaceholderParams struct {
allItems []*Item
lastAction actionType
prompt string
+ executor *util.Executor
}
func (t *Terminal) replacePlaceholder(template string, forcePlus bool, input string, list []*Item) string {
@@ -2535,6 +2537,7 @@ func (t *Terminal) replacePlaceholder(template string, forcePlus bool, input str
allItems: list,
lastAction: t.lastAction,
prompt: t.promptString,
+ executor: t.executor,
})
}
@@ -2595,7 +2598,7 @@ func replacePlaceholder(params replacePlaceholderParams) string {
case escaped:
return match
case match == "{q}" || match == "{fzf:query}":
- return quoteEntry(params.query)
+ return params.executor.QuoteEntry(params.query)
case match == "{}":
replace = func(item *Item) string {
switch {
@@ -2608,13 +2611,13 @@ func replacePlaceholder(params replacePlaceholderParams) string {
case flags.file:
return item.AsString(params.stripAnsi)
default:
- return quoteEntry(item.AsString(params.stripAnsi))
+ return params.executor.QuoteEntry(item.AsString(params.stripAnsi))
}
}
case match == "{fzf:action}":
return params.lastAction.Name()
case match == "{fzf:prompt}":
- return quoteEntry(params.prompt)
+ return params.executor.QuoteEntry(params.prompt)
default:
// token type and also failover (below)
rangeExpressions := strings.Split(match[1:len(match)-1], ",")
@@ -2648,7 +2651,7 @@ func replacePlaceholder(params replacePlaceholderParams) string {
str = strings.TrimSpace(str)
}
if !flags.file {
- str = quoteEntry(str)
+ str = params.executor.QuoteEntry(str)
}
return str
}
@@ -2688,7 +2691,7 @@ func (t *Terminal) executeCommand(template string, forcePlus bool, background bo
return line
}
command := t.replacePlaceholder(template, forcePlus, string(t.input), list)
- cmd := util.ExecCommand(command, false)
+ cmd := t.executor.ExecCommand(command, false)
cmd.Env = t.environ()
t.executing.Set(true)
if !background {
@@ -2965,7 +2968,7 @@ func (t *Terminal) Loop() {
if items[0] != nil {
_, query := t.Input()
command := t.replacePlaceholder(commandTemplate, false, string(query), items)
- cmd := util.ExecCommand(command, true)
+ cmd := t.executor.ExecCommand(command, true)
env := t.environ()
if pwindowSize.Lines > 0 {
lines := fmt.Sprintf("LINES=%d", pwindowSize.Lines)
@@ -3372,27 +3375,21 @@ func (t *Terminal) Loop() {
valid, list := t.buildPlusList(a.a, false)
if valid {
command := t.replacePlaceholder(a.a, false, string(t.input), list)
- shell := os.Getenv("SHELL")
- if len(shell) == 0 {
- shell = "sh"
- }
- shellPath, err := exec.LookPath(shell)
- if err == nil {
- t.tui.Close()
- if t.history != nil {
- t.history.append(string(t.input))
- }
- /*
- FIXME: It is not at all clear why this is required.
- The following command will report 'not a tty', unless we open
- /dev/tty *twice* after closing the standard input for 'reload'
- in Reader.terminate().
- : | fzf --bind 'start:reload:ls' --bind 'enter:become:tty'
- */
- tui.TtyIn()
- util.SetStdin(tui.TtyIn())
- syscall.Exec(shellPath, []string{shell, "-c", command}, os.Environ())
+ t.tui.Close()
+ if t.history != nil {
+ t.history.append(string(t.input))
}
+
+ /*
+ FIXME: It is not at all clear why this is required.
+ The following command will report 'not a tty', unless we open
+ /dev/tty *twice* after closing the standard input for 'reload'
+ in Reader.terminate().
+
+ while : | fzf --bind 'start:reload:ls' --bind 'load:become:tty'; do echo; done
+ */
+ tui.TtyIn()
+ t.executor.Become(tui.TtyIn(), t.environ(), command)
}
case actExecute, actExecuteSilent:
t.executeCommand(a.a, false, a.t == actExecuteSilent, false, false)