Skip to content

Instantly share code, notes, and snippets.

@Konfekt
Created February 21, 2026 10:11
Show Gist options
  • Select an option

  • Save Konfekt/cdee7ff70fe4da538ef4df65779a5e4c to your computer and use it in GitHub Desktop.

Select an option

Save Konfekt/cdee7ff70fe4da538ef4df65779a5e4c to your computer and use it in GitHub Desktop.
Set &findfunc to git-ls-files inside repo and fall back rg, ugrep or fd outside of it
" Purpose: Fast file finding via 'findfunc', with caching and git-aware file listing.
augroup vimrcFind
autocmd!
augroup END
" Scheduling niceness on Linux.
let s:scheduler = has('unix') && executable('chrt') && executable('ionice') ?
\ 'chrt --idle 0 ionice -c2 -n7 ' : ''
" stderr to null, respecting common Windows shells.
if has('win32')
let s:nullerr = (&shell =~? '\v(pwsh|powershell)') ? ' 2>$null' : ' 2> nul'
else
let s:nullerr = ' 2> /dev/null'
endif
" let s:xdg_config = !empty($XDG_CONFIG_HOME) ? expand($XDG_CONFIG_HOME) : expand('~/.config')
" let s:ignorefile = s:xdg_config .. '/grep/ignore'
let s:ignorefile = expand($XDG_CONFIG_HOME) .. '/grep/ignore'
if !filereadable(s:ignorefile)
call mkdir(fnamemodify(s:ignorefile, ':h'), 'p')
call writefile(['.git', 'tags', '!tags/'], s:ignorefile)
endif
" Default file listing command used by the findfunc cache.
if !exists('g:findcmd')
let s:fd = executable('fd') ? 'fd' : (executable('fdfind') ? 'fdfind' : '')
if !empty(s:fd)
" Note: --path-separator required for Unix emulation environments on Windows,
" like Cygwin or Mingw-w64, where the path separator may default to \, but Vim
" thinks it's running under Unix and then wouldn't find the path for editing
let g:findcmd =
\ s:fd
\ .. ' --type=file --path-separator=/ --hidden --follow'
\ .. ' --exclude=.git --exclude=tags --ignore-file=' .. shellescape(s:ignorefile)
\ .. ' --strip-cwd-prefix --color=never ""'
elseif executable('rg')
let g:findcmd =
\ 'rg --files --path-separator=/ --hidden --follow --no-messages'
\ .. ' --ignore-file=' .. shellescape(s:ignorefile)
\ .. ' --no-ignore --color=never --glob=!.git --glob=!tags'
elseif has('win32')
let s:pwsh = executable('pwsh') ? 'pwsh' : (executable('powershell') ? 'powershell' : '')
if !empty(s:pwsh)
let g:findcmd =
\ s:pwsh
\ .. ' -NoProfile -Command'
\ .. ' "Get-ChildItem . -Name -File -Recurse -Force'
\ .. ' | Where-Object { $_ -NotLike ''*\.git\*'' -and $_ -NotLike ''.git\*'' -and $_ -NotLike ''tags'' }"'
else
let g:findcmd = ''
endif
elseif has('unix')
let g:findcmd = 'find -L . -type f -not -path "*/.git/*" -not -name tags -print'
else
let g:findcmd = ''
endif
endif
" Enable :find fuzzy completion via 'findfunc' when available.
if has('patch-9.1.0810')
let s:filescache = []
" See :help findfunc and :help matchfuzzy().
function! s:Find(arg, _) abort
try
if empty(s:filescache)
if empty(get(g:, 'findcmd', ''))
let s:filescache = globpath('.', '**', 1, 1)
call filter(s:filescache, '!isdirectory(v:val)')
call map(s:filescache, "fnamemodify(v:val, ':.')")
else
let s:filescache = systemlist(s:scheduler .. g:findcmd .. s:nullerr)
if has('win32') && g:findcmd =~? '^\s*\%(pwsh\|powershell\)\>'
call map(s:filescache, 'trim(v:val)')
endif
endif
" Clear cache after entering a buffer, since file list can be huge.
autocmd vimrcFind BufEnter * ++once let s:filescache = []
endif
if empty(a:arg) | return s:filescache | endif
let l:max = max([0, &lines - &cmdheight - 1])
if l:max == 0 | return [] | endif
return slice(matchfuzzy(s:filescache, a:arg), 0, l:max - 1)
catch /^Vim:Interrupt/
return []
endtry
endfunction
autocmd vimrcFind CmdlineEnter : let s:filescache = []
set findfunc=<SID>Find
endif
" Prefer git ls-files inside a repo.
if has('patch-9.1.0810') && executable('git')
function! s:OutsideRepo() abort
if exists('*FugitiveGitDir')
return empty(FugitiveGitDir())
endif
let l:_ = system('git rev-parse --is-inside-work-tree' .. s:nullerr)
return v:shell_error != 0
endfunction
let s:findcmd_default = get(g:, 'findcmd', '')
let s:git_ls = 'git ls-files --exclude-from=' .. shellescape(s:ignorefile) .. ' --exclude-standard --cached --others'
function! s:SetFindCmd() abort
let g:findcmd = s:OutsideRepo() ? s:findcmd_default : s:git_ls
endfunction
autocmd vimrcFind VimEnter,DirChanged * call <SID>SetFindCmd()
endif
" Auto-pick the first match on leaving :find if none selected.
if has('patch-9.1.1329')
autocmd vimrcFind CmdlineLeavePre :
\ if get(cmdcomplete_info(), 'matches', []) != [] |
\ let s:info = cmdcomplete_info() |
\ if getcmdline() =~# '^\s*fin\%[d]\s' && (s:info.selected == -1) |
\ call setcmdline('find ' .. s:info.matches[0]) |
\ endif |
\ endif
endif
" Trigger completion automatically for :find once typing starts.
if has('patch-9.0.1576')
augroup vimrcWildTriggerFind
autocmd!
augroup END
autocmd vimrcFind CmdlineChanged :
\ if getcmdline() =~# '\v^\s*fin%[d]\s\S' && !exists('s:wildtrigger_active') |
\ call <SID>EnableWildTrigger() |
\ endif
function! s:EnableWildTrigger() abort
let s:wildmode_saved = &wildmode
set wildmode=noselect,full
autocmd vimrcWildTriggerFind CmdlineChanged : call wildtrigger()
let s:wildtrigger_active = 1
autocmd vimrcWildTriggerFind CmdlineLeavePre : ++once
\ unlet! s:wildtrigger_active |
\ let &wildmode = s:wildmode_saved |
\ autocmd! vimrcWildTriggerFind CmdlineChanged :
endfunction
endif
@Konfekt
Copy link
Author

Konfekt commented Feb 21, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment