Skip to content

Instantly share code, notes, and snippets.

@Konfekt
Last active December 28, 2025 18:46
Show Gist options
  • Select an option

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

Select an option

Save Konfekt/429eb0f4d9a17e31235f49c4716ffddb to your computer and use it in GitHub Desktop.
A command using FZF that takes a range to list only those files altered in last <range> commits
" A command using FZF to list all files in a Git repo;
" takes a range 0, N or N,M to restrict to files that have been, respectively,
" altered, altered in last N commits, altered in-between last N and M commits.
" From https://github.com/junegunn/fzf.vim/blob/879db51d0965515cdaef9b7f6bdeb91c65d2829e/autoload/fzf/vim.vim#L742
function! s:get_git_root(dir)
if empty(a:dir) && exists('*FugitiveWorkTree')
return FugitiveWorkTree()
endif
let dir = len(a:dir) ? a:dir : substitute(split(expand('%:p:h'), '[/\\]\.git\([/\\]\|$\)')[0], '^fugitive://', '', '')
let root = systemlist('git -C ' . shellescape(dir) . ' rev-parse --show-toplevel')[0]
return v:shell_error ? '' : (len(a:dir) ? fnamemodify(a:dir, ':p') : root)
endfunction
" Returns the path to bash executable, or empty string if not found.
function! s:bash() abort
if has('win32')
" On Windows, prefer Git Bash or WSL bash.
let git_bash = $ProgramFiles . '\Git\bin\bash.exe'
if filereadable(git_bash) | return git_bash | endif
if executable('bash') | return 'bash' | endif
return ''
else
" On Unix, just use 'bash' if available.
return executable('bash') ? 'bash' : ''
endif
endfunction
" Escapes a path for safe usage in bash -c "...".
function! s:bash_quote(str) abort
return "'" . substitute(a:str, "'", "'\"'\"'", 'g') . "'"
endfunction
function! s:escape_for_bash(path) abort
if has('win32')
let p = a:path
let p = substitute(p, '^\(\a\):\\', '/mnt/\L\1/', '')
let p = substitute(p, '\\', '/', 'g')
return s:bash_quote(p)
endif
return s:bash_quote(a:path)
endfunction
function! s:GitFiles(bang, range, count, args) abort range
let root = s:get_git_root('')
" No explicit range means original behavior.
if a:range == 0
if empty(root)
return fzf#run(fzf#wrap('FZF'))
endif
return fzf#vim#gitfiles(a:args, fzf#vim#with_preview({}), a:bang)
endif
" Any explicit range requires a git worktree.
if empty(root)
echom getcwd() . ' is not in a git repository'
return 0
endif
" Single-item range :0GitFiles means :GFiles? behavior.
if a:range == 1 && a:count == 0
return fzf#vim#gitfiles('?', fzf#vim#with_preview({ 'placeholder': '' }), a:bang)
endif
let n = a:firstline
let m = a:lastline
if n < 1 || m < 1
echom 'GitFiles range values must be >= 1'
return 0
endif
let filter = has('win32') ? 'findstr /v "^$"' : 'sed -e /^$/d'
" Compute revision endpoints.
if a:range == 1
let rev_from = 'HEAD~' . n
let rev_to = 'HEAD'
let source = 'git log HEAD --max-count=' . n . ' --diff-filter=MA --name-only --pretty=format: | ' . filter
else
" Ex ranges generally enforce n <= m, but keep swapping for robustness.
if n > m
let [n, m] = [m, n]
endif
let rev_from = (m == 0 ? 'HEAD' : 'HEAD~' . m)
let rev_to = (n == 0 ? 'HEAD' : 'HEAD~' . n)
let source = 'git log ' . rev_from . '..' . rev_to . ' --diff-filter=MA --name-only --pretty=format: | ' . filter
endif
let prompt = 'GitFiles(' . rev_from . '..' . rev_to . ')> '
let opts = ['--scheme', 'path', '--prompt', prompt]
" Preview uses bash for consistent quoting and optional delta rendering.
if executable('git') && executable(s:bash())
let bar = has('win32') ? '^|' : '|'
let diff_prefix = 'git -C ' . s:escape_for_bash(root) . ' '
if executable('delta')
let diff =
\ diff_prefix
\ . 'diff --color=always ' . rev_from . '..' . rev_to . ' -- {-1} '
\ . bar . ' delta --width $FZF_PREVIEW_COLUMNS --file-style=omit '
\ . bar . ' sed 1d'
else
let diff =
\ diff_prefix
\ . 'diff --color=always ' . rev_from . '..' . rev_to . ' -- {-1} '
\ . bar . ' sed 1,4d'
endif
let preview_cmd = s:bash() . ' -c "' . diff . '"'
call extend(opts, ['--preview', preview_cmd, '--preview-window', 'right,50%,<70(up,40%)'])
endif
return fzf#run(fzf#wrap('gitfiles', {
\ 'source': source,
\ 'dir': root,
\ 'options': opts,
\ }))
endfunction
command! -bang -range=0 -nargs=? GitFiles <line1>,<line2>call s:GitFiles(<bang>0, <range>, <count>, <q-args>)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment