Skip to content

TUI pagers (diffnav, etc.) break fzf preview panes #491

@jetm

Description

@jetm

Problem

When a user configures a TUI/interactive diff pager via git config pager.diff (e.g., diffnav, tig), all fzf preview panes in forgit show blank output or "Loading..." indefinitely.

This affects every command that uses _forgit_pager diff (or show/blame) inside a preview function — forgit add, forgit log, forgit stash, etc.

Root cause

fzf runs preview commands as subprocesses connected via pipes — there is no TTY. TUI pagers require a terminal to render their interface, so they either:

  • Hang waiting for terminal capabilities that don't exist
  • Exit immediately with no output
  • Produce garbled/empty output

This is not a bug in fzf or the pager — it's a fundamental incompatibility. TUI pagers need a terminal; fzf preview provides a pipe.

The pager resolution chain in _forgit_get_pager reads git config pager.diff, which returns the TUI pager, and there's no distinction between "interactive context" (where TUI pagers work fine) and "preview context" (where they can't work).

Reproduction

# Set a TUI pager
git config pager.diff diffnav

# Run any forgit command with a preview pane
git forgit add    # preview is blank/Loading
git forgit log    # preview is blank/Loading

Current workaround

Setting FORGIT_PAGER or FORGIT_DIFF_PAGER to a non-TUI pager works:

export FORGIT_DIFF_PAGER="delta"
# or
export FORGIT_PAGER="delta"

This overrides the git config pager.diff lookup in _forgit_get_pager, so the TUI pager is never used.

However, this workaround has poor discoverability — users hitting blank previews have no indication of what's wrong or how to fix it.

Questions for discussion

  • Should _forgit_pager detect non-TTY context and automatically fall back? (e.g., check [ -t 1 ])
  • Should preview functions use a separate pager resolution that skips TUI pagers?
  • Or is documenting the FORGIT_*_PAGER workaround sufficient?

I had a PR (#490) attempting one approach (dedicated preview pager function) but it broke per-command pager configurability, so I'm closing it in favor of this discussion.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions