#2627·lf

Add `gitignore` option for automatic gitignore-aware file hiding

Author: Olyxz16Created Jun 25, 2026Updated Jun 25, 2026

Feature description

Add a new boolean option gitignore (default false). When enabled, lf automatically hides files ignored by .gitignore when inside a git worktree, and falls back to normal hiddenfiles behavior otherwise.

Why this cannot be done in user configuration

This was the first thing I tried :

bash
cmd on-cd %{{
    if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
        IGNORED=$(ls -A | git check-ignore --stdin 2>/dev/null | tr '\n' ':')
        lf -remote "send $id set hiddenfiles '.git:${IGNORED}'"
    else
        lf -remote "send $id set hiddenfiles '.*'"
    fi
}}

The problem: on-cd runs in a subprocess that does not block the UI thread. By the time lf -remote delivers the set hiddenfiles command, lf has already rendered the directory using the old patterns. The subsequent remote command forces a re-sort and redraw, producing a visible blink/flash every time you change directories. Caching the value (comparing old vs new) only reduces redundant calls -- it cannot eliminate the IPC delay inherent to the hook architecture.

Proposed implementation

The fix belongs at the directory-loading layer (nav.go), before the UI ever sees the files:

  1. getGitIgnored(dir, names) -- calls git check-ignore --stdin -z once per directory load. Returns a map[string]bool of ignored basenames. If the directory is not inside a git worktree (or git is not installed), returns nil.
  2. readdir -- populates file.gitIgnored for each file when inside a worktree.
  3. dir.sort() -- uses a mutually exclusive filter:
    • Inside a git worktree: hide only gitIgnored files (and .git).
    • Outside a worktree: use normal hiddenfiles patterns.
  4. checkDir -- detects gitignore option toggles and triggers async reloads via the existing directory reload infrastructure (same pattern used for dircounts changes).

Changes

File What changed
opts.go Add gitignore bool to gOpts; default false
eval.go Add toggle handler; uses app.nav.renew() to trigger async reloads
nav.go Add getGitIgnored, file.gitIgnored, dir.gitWorktree, and wire into filter logic
doc.md Add gitignore to Quick Reference and Settings sections

Complexity assessment

  • No new Go dependencies. nav.go already imports os/exec.
  • No new goroutines. The git check runs synchronously inside the existing directory-loading goroutine.
  • Performance: One git check-ignore --stdin -z call per directory load. Negligible overhead when disabled. When enabled, batching via stdin is faster than N individual git check-ignore calls.
  • Platform: Pure Go, works on any platform with git in $PATH.

Usage

bash
set hiddenfiles ".*"
set gitignore
  • Inside a git repo: only gitignored files (plus .git) are hidden. Normal dotfiles (e.g. .bashrc) that are not ignored remain visible.
  • Outside a git repo: normal hiddenfiles behavior applies.
  • Toggle at runtime with :set gitignore!.