[Commits] Add Commits command for browsing git commits

- Enter, CTRL-T/X/V to show commit
- CTRL-D to diff against HEAD
- Multiple selection with TAB / Shift-TAB

Close #13
This commit is contained in:
Junegunn Choi
2015-09-20 01:26:08 +09:00
parent 8cc0b2ea71
commit d8b54082c1
4 changed files with 88 additions and 6 deletions

View File

@@ -61,6 +61,7 @@ Commands
| `History:` | Command history | | `History:` | Command history |
| `History/` | Search history | | `History/` | Search history |
| `Snippets` | Snippets ([UltiSnips][us]) | | `Snippets` | Snippets ([UltiSnips][us]) |
| `Commits` | Git commits (requires [fugitive.vim][f] |
| `Commands` | Commands | | `Commands` | Commands |
| `Helptags` | Help tags <sup id="a1">[1](#helptags)</sup> | | `Helptags` | Help tags <sup id="a1">[1](#helptags)</sup> |
@@ -73,6 +74,7 @@ from [pathogen][pat]. But its functionality is still available via `call
pathogen#helptags()`. [](#a1)) pathogen#helptags()`. [](#a1))
[pat]: https://github.com/tpope/vim-pathogen [pat]: https://github.com/tpope/vim-pathogen
[f]: https://github.com/tpope/vim-fugitive
### Customization ### Customization

View File

@@ -31,6 +31,10 @@ function! s:strip(str)
return substitute(a:str, '^\s*\|\s*$', '', 'g') return substitute(a:str, '^\s*\|\s*$', '', 'g')
endfunction endfunction
function! s:chomp(str)
return substitute(a:str, '\n*$', '', 'g')
endfunction
function! s:escape(path) function! s:escape(path)
return escape(a:path, ' %#''"\') return escape(a:path, ' %#''"\')
endfunction endfunction
@@ -610,6 +614,57 @@ function! fzf#vim#windows(...)
\ 'options': '+m --ansi --tiebreak=begin --header-lines=1'}, a:000) \ 'options': '+m --ansi --tiebreak=begin --header-lines=1'}, a:000)
endfunction endfunction
" ------------------------------------------------------------------
" Commits
" ------------------------------------------------------------------
function! s:commits_sink(lines)
if len(a:lines) < 2
return
endif
let cmd = get(extend({'ctrl-d': ''}, get(g:, 'fzf_action', s:default_action)), a:lines[0], 'e')
let buf = bufnr('')
for idx in range(1, len(a:lines) - 1)
let sha = matchstr(a:lines[idx], '[0-9a-f]\{7}')
if !empty(sha)
if empty(cmd)
if idx > 1
execute 'tab sb' buf
endif
execute 'Gdiff' sha
else
" Since fugitive buffers are unlisted, we can't keep using 'e'
let c = (cmd == 'e' && idx > 1) ? 'tab split' : cmd
execute c 'fugitive://'.s:git_root.'/.git//'.sha
endif
endif
endfor
endfunction
function! fzf#vim#commits(...)
let s:git_root = s:chomp(system('git rev-parse --show-toplevel'))
if v:shell_error
call s:warn('Not in git repository')
return
endif
let options = {
\ 'source': 'git log --graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"',
\ 'sink*': function('s:commits_sink'),
\ 'options': '--ansi --multi --no-sort --reverse --inline-info --prompt "Commits> "'.s:expect()
\ }
let current = expand('%:S')
if !empty(current)
call system('git show '.current)
if !v:shell_error
let options.options .= ',ctrl-d --header ":: Press CTRL-D to diff"'
endif
endif
call s:fzf(options, a:000)
endfunction
" ---------------------------------------------------------------------------- " ----------------------------------------------------------------------------
" fzf#vim#complete - completion helper " fzf#vim#complete - completion helper
" ---------------------------------------------------------------------------- " ----------------------------------------------------------------------------

View File

@@ -1,9 +1,10 @@
fzf-vim.txt fzf-vim Last change: September 1 2015 fzf-vim.txt fzf-vim Last change: September 20 2015
FZF-VIM - TABLE OF CONTENTS *fzf-vim* *fzf-vim-toc* FZF-VIM - TABLE OF CONTENTS *fzf-vim* *fzf-vim-toc*
============================================================================== ==============================================================================
fzf :heart: vim fzf :heart: vim
Rationale Rationale
Why you should use fzf on Vim
Installation Installation
Commands Commands
Customization Customization
@@ -16,7 +17,7 @@ FZF-VIM - TABLE OF CONTENTS *fzf-vim* *fzf-vim-to
FZF :HEART: VIM *fzf-vim-fzf-heart-vim* FZF :HEART: VIM *fzf-vim-fzf-heart-vim*
============================================================================== ==============================================================================
A set of {fzf}{1}-based Vim commands and mappings. Things you can do with {fzf}{1} and Vim.
{1} https://github.com/junegunn/fzf {1} https://github.com/junegunn/fzf
@@ -32,14 +33,29 @@ implementation of the features they can find in the alternative Vim plugins.
This repository is a bundle of fzf-based commands and mappings extracted from This repository is a bundle of fzf-based commands and mappings extracted from
my {.vimrc}{3} to address such needs. They are not designed to be flexible or my {.vimrc}{3} to address such needs. They are not designed to be flexible or
configurable, nor are not guaranteed to be backward-compatible at the moment, configurable, and there's no guarantee of backward-compatibility.
so you might want to treat this repository as a reference.
{1} https://github.com/junegunn/fzf {1} https://github.com/junegunn/fzf
{2} https://github.com/junegunn/fzf#usage-as-vim-plugin {2} https://github.com/junegunn/fzf#usage-as-vim-plugin
{3} https://github.com/junegunn/dotfiles/blob/master/vimrc {3} https://github.com/junegunn/dotfiles/blob/master/vimrc
WHY YOU SHOULD USE FZF ON VIM *fzf-vim-why-you-should-use-fzf-on-vim*
==============================================================================
Because you can and you love fzf.
fzf runs asynchronously and can be orders of magnitude faster than similar Vim
plugins. However, the benefit may not be noticeable if the size of the input
is small, which is the case for many of the commands provided here.
Nevertheless I wrote them anyway since it's really easy to implement custom
selector with fzf.
fzf is an independent command-line program and thus requires an external
terminal emulator when on GVim. You may or may not like the experience. Also
note that fzf currently does not compile on Windows.
INSTALLATION *fzf-vim-installation* INSTALLATION *fzf-vim-installation*
============================================================================== ==============================================================================
@@ -54,6 +70,7 @@ Using {vim-plug}{4}:
COMMANDS *fzf-vim-commands* COMMANDS *fzf-vim-commands*
============================================================================== ==============================================================================
-----------------+--------------------------------------------------------------------- -----------------+---------------------------------------------------------------------
Command | List ~ Command | List ~
-----------------+--------------------------------------------------------------------- -----------------+---------------------------------------------------------------------
@@ -72,16 +89,22 @@ COMMANDS *fzf-vim-commands*
`History:` | Command history `History:` | Command history
`History/` | Search history `History/` | Search history
`Snippets` | Snippets ({UltiSnips}{6}) `Snippets` | Snippets ({UltiSnips}{6})
`Commits` | Git commits (requires {fugitive.vim}{7}
`Commands` | Commands `Commands` | Commands
`Helptags` | Help tags `Helptags` | Help tags [1]
-----------------+--------------------------------------------------------------------- -----------------+---------------------------------------------------------------------
- Most commands support CTRL-T / CTRL-X / CTRL-V key bindings to open in a new - Most commands support CTRL-T / CTRL-X / CTRL-V key bindings to open in a new
tab, a new split, or in a new vertical split. tab, a new split, or in a new vertical split.
- Bang-versions of the commands (e.g. `Ag!`) will open fzf in fullscreen - Bang-versions of the commands (e.g. `Ag!`) will open fzf in fullscreen
(1: `Helptags` will shadow the command of the same name from {pathogen}{8}.
But its functionality is still available via `call pathogen#helptags()`.)
{5} https://github.com/ggreer/the_silver_searcher {5} https://github.com/ggreer/the_silver_searcher
{6} https://github.com/SirVer/ultisnips {6} https://github.com/SirVer/ultisnips
{7} https://github.com/tpope/vim-fugitive
{8} https://github.com/tpope/vim-pathogen
< Customization >_____________________________________________________________~ < Customization >_____________________________________________________________~
@@ -145,8 +168,9 @@ following exceptions:
- `reducer` (funcref) - `reducer` (funcref)
- Reducer transforms the output lines of fzf into a single string value - Reducer transforms the output lines of fzf into a single string value
- `prefix` (string; default: `\k*$`) - `prefix` (string or funcref; default: `\k*$`)
- Regular expression pattern to extract the completion prefix - Regular expression pattern to extract the completion prefix
- Or a function to extract completion prefix
- Both `source` and `options` can be given as funcrefs that take the completion - Both `source` and `options` can be given as funcrefs that take the completion
prefix as the argument and return the final value prefix as the argument and return the final value
- `sink` or `sink*` are not allowed - `sink` or `sink*` are not allowed

View File

@@ -44,6 +44,7 @@ command! -bang Commands call fzf#vim#commands(s:w(<bang>0))
command! -bang Marks call fzf#vim#marks(s:w(<bang>0)) command! -bang Marks call fzf#vim#marks(s:w(<bang>0))
command! -bang Helptags call fzf#vim#helptags(s:w(<bang>0)) command! -bang Helptags call fzf#vim#helptags(s:w(<bang>0))
command! -bang Windows call fzf#vim#windows(s:w(<bang>0)) command! -bang Windows call fzf#vim#windows(s:w(<bang>0))
command! -bang Commits call fzf#vim#commits(s:w(<bang>0))
function! s:history(arg, bang) function! s:history(arg, bang)
let bang = a:bang || a:arg[len(a:arg)-1] == '!' let bang = a:bang || a:arg[len(a:arg)-1] == '!'