Add `gitignore` option for automatic gitignore-aware file hiding
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 :
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:
getGitIgnored(dir, names)-- callsgit check-ignore --stdin -zonce per directory load. Returns amap[string]boolof ignored basenames. If the directory is not inside a git worktree (or git is not installed), returnsnil.readdir-- populatesfile.gitIgnoredfor each file when inside a worktree.dir.sort()-- uses a mutually exclusive filter:- Inside a git worktree: hide only
gitIgnoredfiles (and.git). - Outside a worktree: use normal
hiddenfilespatterns.
- Inside a git worktree: hide only
checkDir-- detectsgitignoreoption toggles and triggers async reloads via the existing directory reload infrastructure (same pattern used fordircountschanges).
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.goalready importsos/exec. - No new goroutines. The git check runs synchronously inside the existing directory-loading goroutine.
- Performance: One
git check-ignore --stdin -zcall per directory load. Negligible overhead when disabled. When enabled, batching via stdin is faster than N individualgit check-ignorecalls. - Platform: Pure Go, works on any platform with git in
$PATH.
Usage
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
hiddenfilesbehavior applies. - Toggle at runtime with
:set gitignore!.
Source: gokcehan/lf