Skip to content

fix(completer): wrap file preview in \sh -c\ for fish compatibility#3089

Open
EmojiPati wants to merge 1 commit intotailcallhq:mainfrom
EmojiPati:fix/file-completer-preview-fish-compat
Open

fix(completer): wrap file preview in \sh -c\ for fish compatibility#3089
EmojiPati wants to merge 1 commit intotailcallhq:mainfrom
EmojiPati:fix/file-completer-preview-fish-compat

Conversation

@EmojiPati
Copy link
Copy Markdown
Contributor

Summary

Fix the @-completion file preview so it renders correctly when the user's login shell is fish (or any other non-POSIX shell).

Context

fzf dispatches --preview commands through $SHELL. The preview template emitted by InputCompleter is a POSIX shell snippet that uses if [ -d … ]; then … else … fi to decide between a directory listing and a bat/cat render. Under fish, evaluating that snippet fails with:

fish: Missing end to balance this if statement

Opening a zsh session from a terminal does not fix this, because fzf reads the $SHELL environment variable from the process it was spawned under, not the currently active shell. For users whose login shell is fish, the file preview pane stays broken even after switching shells.

Changes

  • crates/forge_main/src/completer/input_completer.rs: wrap the preview script in sh -c '…' _ {2} so the POSIX body is always evaluated by sh regardless of $SHELL. The {2} placeholder (the path column of the fzf list) is forwarded positionally and read inside the script as "$1", preserving paths that contain whitespace or shell metacharacters.
  • Extract the command builder into a pure build_preview_cmd function and add two unit tests covering the bat and cat branches.

Key implementation details

  • The outer layer quoting is single-quoted POSIX, the inner expansions stay double-quoted around "$1", so fzf's native quoteEntry output (e.g. 'path with space/file.rs') composes correctly without requiring any additional escaping from our side.
  • Using _ as $0 filler is the standard trick for invoking sh -c 'script' arg1 where the first positional argument is the real input.

Testing

cargo +nightly fmt --all -- --check
cargo +nightly clippy --all-features --workspace --all-targets -- -D warnings
cargo test -p forge_main --lib

Manual verification on a fish login shell:

  1. echo $SHELL/usr/bin/fish
  2. Launch forge, type @ and start typing a filename.
  3. The preview pane now shows the bat output for files / ls -la output for directories, instead of the fish: Missing end to balance this if statement error.

fzf dispatches `--preview` commands through `$SHELL`, so when the
user's login shell is fish the `@`-completion preview fails with
"fish: Missing end to balance this if statement" — fish cannot parse
the POSIX `if [ … ]; then … fi` body. Wrapping the script in `sh -c`
makes the preview render under any non-POSIX login shell.
@github-actions github-actions bot added the type: fix Iterations on existing features or infrastructure. label Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix Iterations on existing features or infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant