diff --git a/README.md b/README.md index bcf6eb9d..f0dba33f 100644 --- a/README.md +++ b/README.md @@ -237,14 +237,15 @@ a command or define a variation of it by calling its corresponding function. | Command | Vim function | | --- | --- | -| `Files` | `fzf#vim#files(dir, [spec dict], [fullscreen bool])` | -| `GFiles` | `fzf#vim#gitfiles(git_options, [spec dict], [fullscreen bool])` | -| `GFiles?` | `fzf#vim#gitfiles('?', [spec dict], [fullscreen bool])` | -| `Buffers` | `fzf#vim#buffers([query string], [bufnrs list], [spec dict], [fullscreen bool])` | -| `Colors` | `fzf#vim#colors([spec dict], [fullscreen bool])` | -| `Rg` | `fzf#vim#grep(command, [spec dict], [fullscreen bool])` | -| `RG` | `fzf#vim#grep2(command_prefix, query, [spec dict], [fullscreen bool])` | -| ... | ... | +| `Files` | `fzf#vim#files(dir, [spec dict], [fullscreen bool])` | +| `GFiles` | `fzf#vim#gitfiles(git_options, [spec dict], [fullscreen bool])` | +| `GFiles?` | `fzf#vim#gitfiles('?', [spec dict], [fullscreen bool])` | + `GBranchFiles` | `fzf#vim#gitfiles_branch(git_options, [spec dict], [fullscreen bool])` | +| `Buffers` | `fzf#vim#buffers([query string], [bufnrs list], [spec dict], [fullscreen bool])` | +| `Colors` | `fzf#vim#colors([spec dict], [fullscreen bool])` | +| `Rg` | `fzf#vim#grep(command, [spec dict], [fullscreen bool])` | +| `RG` | `fzf#vim#grep2(command_prefix, query, [spec dict], [fullscreen bool])` | +| ... | ... | (We can see that the last two optional arguments of each function are identical. They are directly passed to `fzf#wrap` function. If you haven't diff --git a/autoload/fzf/vim.vim b/autoload/fzf/vim.vim index 6fe31a13..0325034e 100755 --- a/autoload/fzf/vim.vim +++ b/autoload/fzf/vim.vim @@ -747,6 +747,60 @@ function! fzf#vim#gitfiles(args, ...) return s:fzf('gfiles-diff', wrapped, a:000) endfunction + +" ------------------------------------------------------------------ +" GitBranchFiles +" ------------------------------------------------------------------ +function! fzf#vim#git_branch_files(args, ...) + let dir = get(get(a:, 1, {}), 'dir', '') + let root = s:get_git_root(dir) + if empty(root) + return s:warn('Not in git repo') + endif + + " We extract the base-branch using sed and git rev-parse on ref HEAD + " This help us to extract the base branch that can be 'master' 'main' or something else. + let base_branch = 'git show-branch | grep "\\*" | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed "s/.*\\[//;s/\\].*//"' + + " The Prefix command is then build by composing the diff stats on the current branch HEAD + " from the base-branch + let prefix = 'git diff --stat $(git merge-base HEAD $('.base_branch.'))' + + if a:args != '?' + " Get the list of changed files in the current branch + let source = prefix . ' --name-only' + let options = ' --prompt "GitBranchFiles> "' + + return s:fzf('gbranchfiles', { + \ 'source': source, + \ 'dir': root, + \ 'options': options + \}, a:000) + endif + + let bar = s:is_win ? '^|' : '|' + let preview = printf( + \ s:bash() . ' -c "if [[ {1} =~ M ]]; then %s; else %s {-1}; fi"', + \ executable('delta') + \ ? prefix . ' --patch -- {-1} ' . bar . ' delta --width $FZF_PREVIEW_COLUMNS --file-style=omit ' . bar . ' sed 1d' + \ : prefix . ' --patch --color=always -- {-1} ' . bar . ' sed 1,4d', + \ s:escape_for_bash(s:bin.preview)) + let wrapped = fzf#wrap({ + \ 'source': prefix, + \ 'dir': root, + \ 'options': ['--ansi', '--multi', '--nth', '2..,..', '--tiebreak=index', '--prompt', 'GitBranchFiles?> ', '--preview', preview] + \}) + call s:remove_layout(wrapped) + let wrapped.common_sink = remove(wrapped, 'sink*') + function! wrapped.newsink(lines) + let lines = extend(a:lines[0:0], map(a:lines[1:], 'substitute(v:val[3:], ".* -> ", "", "")')) + return self.common_sink(lines) + endfunction + let wrapped['sink*'] = remove(wrapped, 'newsink') + return s:fzf('gbranchfiles-diff', wrapped, a:000) +endfunction + + " ------------------------------------------------------------------ " Buffers " ------------------------------------------------------------------ diff --git a/doc/fzf-vim.txt b/doc/fzf-vim.txt index d2179d27..d8358be0 100644 --- a/doc/fzf-vim.txt +++ b/doc/fzf-vim.txt @@ -294,14 +294,15 @@ command or define a variation of it by calling its corresponding function. ----------+--------------------------------------------------------------------------------- Command | Vim function ~ ----------+--------------------------------------------------------------------------------- - `Files` | `fzf#vim#files(dir, [spec dict], [fullscreen bool])` - `GFiles` | `fzf#vim#gitfiles(git_options, [spec dict], [fullscreen bool])` - `GFiles?` | `fzf#vim#gitfiles('?', [spec dict], [fullscreen bool])` - `Buffers` | `fzf#vim#buffers([query string], [bufnrs list], [spec dict], [fullscreen bool])` - `Colors` | `fzf#vim#colors([spec dict], [fullscreen bool])` - `Rg` | `fzf#vim#grep(command, [spec dict], [fullscreen bool])` - `RG` | `fzf#vim#grep2(command_prefix, query, [spec dict], [fullscreen bool])` - ... | ... + `Files` | `fzf#vim#files(dir, [spec dict], [fullscreen bool])` + `GFiles` | `fzf#vim#gitfiles(git_options, [spec dict], [fullscreen bool])` + `GFiles?` | `fzf#vim#gitfiles('?', [spec dict], [fullscreen bool])` + `GBranchFiles` | `fzf#vim#git_branch_files(git_options, [spec dict], [fullscreen bool])` + `Buffers` | `fzf#vim#buffers([query string], [bufnrs list], [spec dict], [fullscreen bool])` + `Colors` | `fzf#vim#colors([spec dict], [fullscreen bool])` + `Rg` | `fzf#vim#grep(command, [spec dict], [fullscreen bool])` + `RG` | `fzf#vim#grep2(command_prefix, query, [spec dict], [fullscreen bool])` + ... | ... ----------+--------------------------------------------------------------------------------- (We can see that the last two optional arguments of each function are diff --git a/plugin/fzf.vim b/plugin/fzf.vim index 622fb83e..80e9658b 100644 --- a/plugin/fzf.vim +++ b/plugin/fzf.vim @@ -53,6 +53,7 @@ endfunction call s:defs([ \'command! -bang -nargs=? -complete=dir Files call fzf#vim#files(, fzf#vim#with_preview(), 0)', \'command! -bang -nargs=? GitFiles call fzf#vim#gitfiles(, fzf#vim#with_preview( == "?" ? { "placeholder": "" } : {}), 0)', +\'command! -bang -nargs=? GitBranchFiles call fzf#vim#git_branch_files(, fzf#vim#with_preview( == "?" ? { "placeholder": "" } : {}), 0)', \'command! -bang -nargs=? GFiles call fzf#vim#gitfiles(, fzf#vim#with_preview( == "?" ? { "placeholder": "" } : {}), 0)', \'command! -bar -bang -nargs=? -complete=buffer Buffers call fzf#vim#buffers(, fzf#vim#with_preview({ "placeholder": "{1}" }), 0)', \'command! -bang -nargs=* Lines call fzf#vim#lines(, 0)',