junegunn / fzf

:cherry_blossom: A command-line fuzzy finder

Home Page:https://junegunn.github.io/fzf/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature Request] Customizable shell command flag for command execution

LangLangBart opened this issue · comments

Checklist

  • I have read through the manual page (man fzf)
  • I have searched through the existing issues
  • For bug reports, I have checked if the bug is reproducible in the latest version of fzf

Output of fzf --version

0.50.0 (brew)

OS

  • Linux
  • macOS
  • Windows
  • Etc.

Shell

  • bash
  • zsh
  • fish

Problem / Steps to reproduce

This report was created from a discussion on a discarded PR: #3726


Issue

fzf currently executes commands with $SHELL and a hardcoded -c flag.

// ExecCommandWith executes the given command with the specified shell
func ExecCommandWith(shell string, command string, setpgid bool) *exec.Cmd {
cmd := exec.Command(shell, "-c", command)
if setpgid {
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
}
return cmd
}

If a user wants to use a different tool with a different flag to execute commands, they must prepend the desired command to each string, making proper quoting more cumbersome and leading to repetitive addition of the command.

# [bun] https://github.com/oven-sh/bun
fzf --bind "start:reload:bun --print \"Object.keys(Bun.env).sort().join('\n')\""

Feature Proposal

Ability to change the flag that is passed to the $SHELL command.

If the flag would be subject to change, then one would only need to write the string.

# Syntax example, not actual usage
SHELL=$(which bun) FZF_SHELL_FLAG="--print" \
  fzf --bind "start:reload:Object.keys(Bun.env).sort().join('\n')"

# Different syntax example proposed by the maintainer
fzf --with-shell "bun --print" \
  --bind "start:reload:Object.keys(Bun.env).sort().join('\n')"

Here are a few examples of tools with their corresponding flags to illustrate the variety of flags that might be used:

  • jsc -e: a short, single-letter option 1
  • bun --print: a long, word-based option 2
  • osascript -l JavaScript -e: multiple short, single-letter options and an argument 3

Workaround

The maintainer provided a workaround 4.

fzf2() (
  export SHELL=/tmp/fzfsh
  if ! [[ -x $SHELL ]]; then
    echo '#!/bin/sh' > "$SHELL"
    echo 'shift; echo "$@"' >> "$SHELL"
    chmod +x "$SHELL"
  fi
  command fzf "$@"
)

fzf2 --preview 'run this command: {}'

Footnotes

  1. JSC – WebKit

  2. Bun — A fast all-in-one JavaScript runtime

  3. JXA - JavaScript for Automation

  4. PR #3726 (comment)

The suggestion here is to add an option similar to shellcmdflag of Vim: https://vimdoc.sourceforge.net/htmldoc/options.html#'shellcmdflag'

Personally, I don't like having to set two environment variables (or options) to make it work. It doesn't feel much more ergonomic than writing a wrapper script. I'd prefer to add an option that looks like fzf --with-shell "$SHELL -c" as commented in the previous pull request though it has it's own issue.

Sure, using --with-shell is much clearer and simpler to write than using two environment variables.


It's important to mention in the documentation that, if this feature is implemented, one should not set
the flags to -ic for the typical SHELL (zsh, …), as it usually ends badly. Below are some instances where
doing so has caused issues: