1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-23 07:00:04 +08:00

chore(bundle): use bundle fugitive & dispatch

This commit is contained in:
wsdjeg 2022-07-24 16:26:12 +08:00
parent 4ee6dfe43f
commit b0dcd1bb84
23 changed files with 12275 additions and 2 deletions

View File

@ -64,8 +64,8 @@ function! SpaceVim#layers#git#plugins() abort
if s:git_plugin ==# 'gina'
call add(plugins, [g:_spacevim_root_dir . 'bundle/gina.vim', { 'merged' : 0}])
elseif s:git_plugin ==# 'fugitive'
call add(plugins, ['tpope/vim-fugitive', { 'merged' : 0}])
call add(plugins, ['tpope/vim-dispatch', { 'merged' : 0}])
call add(plugins, [g:_spacevim_root_dir . 'bundle/vim-fugitive', { 'merged' : 0}])
call add(plugins, [g:_spacevim_root_dir . 'bundle/vim-dispatch', { 'merged' : 0}])
elseif s:git_plugin ==# 'gita'
call add(plugins, ['lambdalisue/vim-gita', { 'on_cmd' : 'Gita'}])
else

View File

@ -0,0 +1,2 @@
github: tpope
custom: ["https://www.paypal.me/vimpope"]

1
bundle/vim-dispatch/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/doc/tags

View File

@ -0,0 +1 @@
See the [contribution guidelines for pathogen.vim](https://github.com/tpope/vim-pathogen/blob/master/CONTRIBUTING.markdown).

154
bundle/vim-dispatch/README.markdown vendored Normal file
View File

@ -0,0 +1,154 @@
# dispatch.vim
Leverage the power of Vim's compiler plugins without being bound by
synchronicity. Kick off builds and test suites using one of several
asynchronous adapters (including tmux, screen, iTerm, Windows, and a headless
mode), and when the job completes, errors will be loaded and parsed
automatically.
If that doesn't excite you, then perhaps [this video][teaser] will change your
mind.
[teaser]: http://vimeo.com/tpope/vim-dispatch-teaser
## Installation
Install using your favorite package manager, or use Vim's built-in package
support:
mkdir -p ~/.vim/pack/tpope/start
cd ~/.vim/pack/tpope/start
git clone https://tpope.io/vim/dispatch.git
vim -u NONE -c "helptags dispatch/doc" -c q
## Usage
The core of Vim's compiler system is `:make`, a command similar to `:grep`
that runs a build tool and parses the resulting errors. The default build
tool is of course `make`, but you can switch it (and the associated error
parser) with `:compiler`. There are lots of built-in compilers, and they do
more than just compile things. Plus you can make your own.
We'll start by looking at dispatch.vim's `:make` wrapper `:Make`, and then
move on to higher abstractions.
### Foreground builds
Kick off quick tasks with `:Make`. What happens next depends on which adapter
takes charge.
* If you're in tmux, a small split will be opened at the bottom.
* On Windows, a minimized cmd.exe window is spawned.
* Otherwise, you get a plain old `:make` invocation.
When the task completes, the window closes, the errors are loaded and parsed,
and the quickfix window automatically opens. At no point will your focus be
stolen.
### Background builds
Use `:Make!` for longer running tasks, like "run the entire test suite".
* If you're in tmux or GNU screen, a new window is created in the background.
* Windows still spawns a minimized cmd.exe window.
* Otherwise, you get a headless invocation. You can't see it, but it's
running in the background.
You won't be interrupted with a quickfix window for a background build.
Instead, open it at your leisure with `:Copen`.
You can also use `:Copen` on a build that's still running to retrieve and
parse any errors that have already happened.
### Compiler switching
As hinted earlier, it's easy to switch compilers.
:compiler rubyunit
:make test/models/user_test.rb
Wait, that's still twice as many commands as it needs to be. Plus, it
requires you to make the leap from `testrb` (the executable) to `rubyunit`
(the compiler plugin). The `:Dispatch` command looks for a compiler for an
executable and sets it up automatically.
:Dispatch testrb test/models/user_test.rb
If no compiler plugin is found, `:Dispatch` simply captures all output.
:Dispatch bundle install
As with `:make`, you can use `%` expansions for the current filename.
:Dispatch rspec %
The `:Dispatch` command switches the compiler back afterwards, so you can pick
a primary compiler for `:Make`, and use `:Dispatch` for secondary concerns.
### Default dispatch
With no arguments, `:Dispatch` looks for a `b:dispatch` variable. You
can set it interactively, or in an autocommand:
autocmd FileType java let b:dispatch = 'javac %'
If no `b:dispatch` is found, it falls back to `:Make`.
`:Dispatch` makes a great map. By default dispatch.vim provides `` `<CR>`` for
`:Dispatch<CR>`. You can find all default maps under `:h dispatch-maps`.
### Focusing
Use `:FocusDispatch` (or just `:Focus`) to temporarily, globally override the
default dispatch:
:Focus rake spec:models
Now every bare call to `:Dispatch` will call `:Dispatch rake spec:models`.
You'll be getting a lot of mileage out of that `:Dispatch` map.
Use `:Focus!` to reset back to the default.
### Spawning interactive processes
Sometimes you just want to kick off a process without any output capturing or
error parsing. That's what `:Start` is for:
:Start lein repl
Unlike `:Make`, the new window will be in focus, since the idea is that you
want to interact with it. Use `:Start!` to launch it in the background.
### Plugin support
Using dispatch.vim from a plugin is a simple matter of checking for and using
`:Make` and `:Start` if they're available instead of `:make` and `:!`. Your
favorite plugin already supports it, assuming your favorite plugin is
[rails.vim](https://github.com/tpope/vim-rails).
## FAQ
> How can I have `:Dispatch!` or `:Make!` open the quickfix window on
> completion?
Use `:Dispatch` or `:Make`. The entire point of the `!` is to run in the
background without interrupting you.
> But that blocks Vim.
Then the adapter in use doesn't support foreground builds. Adjust your setup.
## Self-Promotion
Like dispatch.vim? Follow the repository on
[GitHub](https://github.com/tpope/vim-dispatch) and vote for it on
[vim.org](http://www.vim.org/scripts/script.php?script_id=4504). And if
you're feeling especially charitable, follow [tpope](http://tpo.pe/) on
[Twitter](http://twitter.com/tpope) and
[GitHub](https://github.com/tpope).
## License
Copyright © Tim Pope. Distributed under the same terms as Vim itself.
See `:help license`.

1399
bundle/vim-dispatch/autoload/dispatch.vim vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
" dispatch.vim headless strategy
if exists('g:autoloaded_dispatch_headless')
finish
endif
let g:autoloaded_dispatch_headless = 1
function! dispatch#headless#handle(request) abort
if !a:request.background || &shell !~# 'sh'
return 0
endif
if a:request.action ==# 'make'
let command = dispatch#prepare_make(a:request)
elseif a:request.action ==# 'start'
let command = dispatch#prepare_start(a:request)
else
return 0
endif
if &shellredir =~# '%s'
let redir = printf(&shellredir, '/dev/null')
else
let redir = &shellredir . ' ' . '/dev/null'
endif
call system(&shell.' '.&shellcmdflag.' '.shellescape(command).redir.' &')
return !v:shell_error
endfunction
function! dispatch#headless#activate(pid) abort
return 0
endfunction

View File

@ -0,0 +1,141 @@
" dispatch.vim iTerm strategy
if exists('g:autoloaded_dispatch_iterm')
finish
endif
let g:autoloaded_dispatch_iterm = 1
function! dispatch#iterm#handle(request) abort
if $TERM_PROGRAM !=# 'iTerm.app' && !((has('gui_macvim') || has('gui_vimr')) && has('gui_running'))
return 0
endif
if a:request.action ==# 'start'
return dispatch#iterm#spawn(dispatch#prepare_start(a:request), a:request, !a:request.background)
endif
endfunction
function! dispatch#iterm#is_modern_version() abort
return s:osascript(
\ 'on modernversion(version)',
\ 'set olddelimiters to AppleScript''s text item delimiters',
\ 'set AppleScript''s text item delimiters to "."',
\ 'set thearray to every text item of version',
\ 'set AppleScript''s text item delimiters to olddelimiters',
\ 'set major to item 1 of thearray',
\ 'set minor to item 2 of thearray',
\ 'set veryminor to item 3 of thearray',
\ 'if major < 2 then return false',
\ 'if major > 2 then return true',
\ 'if minor < 9 then return false',
\ 'if minor > 9 then return true',
\ 'if veryminor < 20140903 then return false',
\ 'return true',
\ 'end modernversion',
\ 'tell application "iTerm"',
\ 'if not my modernversion(version) then error',
\ 'end tell')
endfunction
function! dispatch#iterm#spawn(command, request, activate) abort
if dispatch#iterm#is_modern_version()
return dispatch#iterm#spawn3(a:command, a:request, a:activate)
else
return dispatch#iterm#spawn2(a:command, a:request, a:activate)
endif
endfunction
function! dispatch#iterm#spawn2(command, request, activate) abort
let script = dispatch#isolate(a:request, [],
\ dispatch#set_title(a:request), a:command)
return s:osascript(
\ 'if application "iTerm" is not running',
\ 'error',
\ 'end if') && s:osascript(
\ 'tell application "iTerm"',
\ 'tell the current terminal',
\ 'set oldsession to the current session',
\ 'tell (make new session)',
\ 'set name to ' . s:escape(a:request.title),
\ 'set title to ' . s:escape(a:request.expanded),
\ 'exec command ' . s:escape(script),
\ a:request.background || !has('gui_running') ? 'select oldsession' : '',
\ 'end tell',
\ 'end tell',
\ a:activate ? 'activate' : '',
\ 'end tell')
endfunction
function! dispatch#iterm#spawn3(command, request, activate) abort
let script = dispatch#isolate(a:request, [],
\ dispatch#set_title(a:request), a:command)
return s:osascript(
\ 'if application "iTerm" is not running',
\ 'error',
\ 'end if') && s:osascript(
\ 'tell application "iTerm"',
\ 'tell the current window',
\ 'set oldtab to the current tab',
\ 'set newtab to (create tab with default profile command ' . s:escape(script) . ')',
\ 'tell current session of newtab',
\ 'set name to ' . s:escape(a:request.title),
\ 'set title to ' . s:escape(a:request.expanded),
\ 'end tell',
\ a:request.background || !has('gui_running') ? 'select oldtab' : '',
\ 'end tell',
\ a:activate ? 'activate' : '',
\ 'end tell')
endfunction
function! dispatch#iterm#activate(pid) abort
if dispatch#iterm#is_modern_version()
return dispatch#iterm#activate3(a:pid)
else
return dispatch#iterm#activate2(a:pid)
endif
endfunction
function! dispatch#iterm#activate2(pid) abort
let tty = matchstr(system('ps -p '.a:pid), 'tty\S\+')
if !empty(tty)
return s:osascript(
\ 'if application "iTerm" is not running',
\ 'error',
\ 'end if') && s:osascript(
\ 'tell application "iTerm"',
\ 'activate',
\ 'tell the current terminal',
\ 'select session id "/dev/'.tty.'"',
\ 'end tell',
\ 'end tell')
endif
endfunction
function! dispatch#iterm#activate3(pid) abort
let tty = matchstr(system('ps -p '.a:pid), 'tty\S\+')
if !empty(tty)
return s:osascript(
\ 'if application "iTerm" is not running',
\ 'error',
\ 'end if') && s:osascript(
\ 'tell application "iTerm"',
\ 'activate',
\ 'tell the current window',
\ 'repeat with atab in tabs',
\ 'repeat with asession in sessions',
\ 'if (tty) = ' . tty,
\ 'select atab',
\ 'end repeat',
\ 'end repeat',
\ 'end tell',
\ 'end tell')
endif
endfunction
function! s:osascript(...) abort
call system('osascript'.join(map(copy(a:000), '" -e ".shellescape(v:val)'), ''))
return !v:shell_error
endfunction
function! s:escape(string) abort
return '"'.escape(a:string, '"\').'"'
endfunction

View File

@ -0,0 +1,142 @@
" dispatch.vim job strategy
if exists('g:autoloaded_dispatch_job')
finish
endif
let g:autoloaded_dispatch_job = 1
if !exists('s:waiting')
let s:waiting = {}
endif
let g:dispatch_waiting_jobs = s:waiting
function! dispatch#job#handle(request) abort
if !get(g:, 'dispatch_experimental', 1)
return 0
endif
if a:request.action !=# 'make'
return 0
endif
if exists('*job_start')
if has('win32')
let cmd = &shell . ' ' . &shellcmdflag . ' ' . dispatch#windows#escape(a:request.expanded)
else
let cmd = split(&shell) + split(&shellcmdflag) + [a:request.expanded]
endif
let job = job_start(cmd, {
\ 'mode': 'raw',
\ 'callback': function('s:output'),
\ 'close_cb': function('s:closed'),
\ 'exit_cb': function('s:exit'),
\ })
call ch_close_in(job)
let a:request.pid = job_info(job).process
let a:request.job = job
let ch_id = ch_info(job_info(job).channel).id
let s:waiting[ch_id] = {'request': a:request, 'output': ['']}
elseif exists('*jobpid') && exists('*jobstart')
let job_id = jobstart(a:request.expanded, {
\ 'on_stdout': function('s:output'),
\ 'on_stderr': function('s:output'),
\ 'on_exit': function('s:complete'),
\ })
call chanclose(job_id, 'stdin')
let a:request.pid = jobpid(job_id)
let a:request.job = job_id
let s:waiting[job_id] = {'request': a:request, 'output': ['']}
else
return 0
endif
let a:request.handler = 'job'
call writefile([], a:request.file)
call writefile([a:request.pid], a:request.file . '.pid')
return 2
endfunction
function! s:complete(id, status, ...) abort
let waiting = remove(s:waiting, a:id)
call writefile([a:status], waiting.request.file . '.complete')
call DispatchComplete(waiting.request.id)
endfunction
function! s:closed(ch) abort
let id = ch_info(a:ch).id
if has_key(s:waiting, id) && has_key(s:waiting[id], 'exit_status')
call s:complete(id, s:waiting[id].exit_status)
endif
endfunction
function! s:exit(job, status) abort
let ch = job_info(a:job).channel
let info = ch_info(ch)
if info.status ==# 'closed'
return s:complete(info.id, a:status)
else
let s:waiting[info.id].exit_status = a:status
endif
endfunction
function! s:output(ch, output, ...) abort
if a:0
" nvim
let waiting = s:waiting[a:ch]
let output = a:output
else
" vim
let waiting = s:waiting[ch_info(a:ch).id]
let output = split(a:output, "\n", 1)
endif
let request = waiting.request
call writefile(output, request.file, 'ab')
let waiting.output[-1] .= remove(output, 0)
call extend(waiting.output, output)
if dispatch#request(get(getqflist({'title': 1}), 'title', '')) is# request && len(waiting.output) > 1
let lefm = &l:efm
let gefm = &g:efm
let makeprg = &l:makeprg
let compiler = get(b:, 'current_compiler', '')
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : exists(':tcd') && haslocaldir(-1) ? 'tcd' : 'cd'
let dir = getcwd()
let modelines = &modelines
try
let &modelines = 0
let b:current_compiler = get(request, 'compiler', '')
if empty(b:current_compiler)
unlet! b:current_compiler
endif
exe cd fnameescape(request.directory)
let &l:efm = request.format
let &g:efm = request.format
let &l:makeprg = request.command
caddexpr remove(waiting.output, 0, -2)
finally
let &modelines = modelines
exe cd fnameescape(dir)
let &l:efm = lefm
let &g:efm = gefm
let &l:makeprg = makeprg
if empty(compiler)
unlet! b:current_compiler
else
let b:current_compiler = compiler
endif
endtry
cbottom
endif
endfunction
function! dispatch#job#kill(pid, force) abort
let request = dispatch#request('job/' . a:pid)
if exists('*job_stop')
return job_stop(request.job, a:force ? 'kill' : 'hup')
elseif exists('*jobstop')
call jobstop(request.job)
return 1
endif
endfunction
function! dispatch#job#activate(pid) abort
return 0
endfunction

View File

@ -0,0 +1,44 @@
" dispatch.vim GNU Screen strategy
if exists('g:autoloaded_dispatch_screen')
finish
endif
let g:autoloaded_dispatch_screen = 1
function! dispatch#screen#handle(request) abort
if empty($STY) || !executable('screen')
return 0
endif
if a:request.action ==# 'make'
if !get(a:request, 'background', 0) && !dispatch#has_callback()
return 0
endif
return dispatch#screen#spawn(dispatch#prepare_make(a:request), a:request)
elseif a:request.action ==# 'start'
return dispatch#screen#spawn(dispatch#prepare_start(a:request), a:request)
endif
endfunction
function! dispatch#screen#spawn(command, request) abort
let command = 'screen -ln -fn -t '.dispatch#shellescape(a:request.title)
\ . ' ' . &shell . ' ' . &shellcmdflag . ' '
\ . shellescape('exec ' . dispatch#isolate(a:request,
\ ['STY', 'WINDOW'], dispatch#set_title(a:request), a:command))
silent execute dispatch#bang(command)
if (a:request.background || a:request.action !=# 'start') && !has('gui_running') && !has('nvim')
silent !screen -X other
endif
return 1
endfunction
function! dispatch#screen#activate(pid) abort
let out = system('ps ewww -p '.a:pid)
if empty($STY) || stridx(out, 'STY='.$STY) < 0
return 0
endif
let window = matchstr(out, 'WINDOW=\zs\d\+')
if !empty(window)
silent execute '!screen -X select '.window
return !v:shell_error
endif
endfunction

View File

@ -0,0 +1,84 @@
" dispatch.vim terminal strategy
if exists('g:autoloaded_dispatch_terminal')
finish
endif
let g:autoloaded_dispatch_terminal = 1
if !exists('s:waiting')
let s:waiting = {}
endif
function! dispatch#terminal#handle(request) abort
if !get(g:, 'dispatch_experimental', 1)
return 0
endif
if !(has('terminal') || has('nvim')) || a:request.action !=# 'start'
return 0
endif
let a:request.handler = 'terminal'
let winid = win_getid()
if has('nvim')
exe a:request.mods 'new'
let options = {
\ 'on_exit': function('s:exit', [a:request]),
\ }
let job = termopen(a:request.expanded, options)
let a:request.bufnr = bufnr('')
let a:request.pid = jobpid(job)
if !a:request.background
startinsert
endif
else
let winid = win_getid()
exe a:request.mods 'split'
let options = {
\ 'exit_cb': function('s:exit', [a:request]),
\ 'term_name': '!' . a:request.expanded,
\ 'term_finish': 'open',
\ 'curwin': 1,
\ }
let a:request.bufnr = term_start([&shell, &shellcmdflag, a:request.expanded], options)
let job = term_getjob(a:request.bufnr)
let a:request.pid = job_info(job).process
endif
if a:request.background
call win_gotoid(winid)
endif
let s:waiting[a:request.pid] = a:request
call writefile([a:request.pid], a:request.file . '.pid')
return 1
endfunction
function! s:exit(request, job, status, ...) abort
unlet! s:waiting[a:request.pid]
call writefile([a:status], a:request.file . '.complete')
let wait = get(a:request, 'wait', 'error')
if wait ==# 'never' || (wait !=# 'always' && a:status == 0)
silent exec 'bdelete! ' . a:request.bufnr
endif
endfunction
function! dispatch#terminal#activate(pid) abort
if has_key(s:waiting, a:pid)
let request = s:waiting[a:pid]
let pre = &switchbuf
try
let &switchbuf = 'useopen,usetab'
silent exe request.mods 'sbuffer' request.bufnr
finally
let &switchbuf = pre
endtry
return 1
endif
return 0
endfunction

View File

@ -0,0 +1,130 @@
" dispatch.vim tmux strategy
if exists('g:autoloaded_dispatch_tmux')
finish
endif
let g:autoloaded_dispatch_tmux = 1
let s:waiting = {}
let s:make_pane = tempname()
function! dispatch#tmux#handle(request) abort
let session = get(g:, 'tmux_session', '')
if empty($TMUX) && empty(''.session) || !executable('tmux')
return 0
endif
if !empty(system('tmux has-session -t '.shellescape(session))[0:-2])
return ''
endif
if a:request.action ==# 'make'
if !get(a:request, 'background', 0) && !dispatch#has_callback() &&
\ !empty(''.session) && session !=# system('tmux display-message -p "#S"')[0:-2]
return 0
endif
return dispatch#tmux#make(a:request)
elseif a:request.action ==# 'start'
let command = 'tmux new-window -P -t '.shellescape(session.':')
let command .= ' -n '.shellescape(a:request.title)
if a:request.background
let command .= ' -d'
endif
let command .= ' ' . shellescape('exec ' . dispatch#isolate(
\ a:request, ['TMUX', 'TMUX_PANE'],
\ dispatch#set_title(a:request),
\ dispatch#prepare_start(a:request)))
call system(command)
return 1
endif
endfunction
function! dispatch#tmux#make(request) abort
let pipepane = get(g:, 'dispatch_tmux_pipe_pane', 0)
\ && a:request.format !~# '%\\[er]'
let session = get(g:, 'tmux_session', '')
let script = dispatch#isolate(a:request, ['TMUX', 'TMUX_PANE'],
\ call('dispatch#prepare_make', [a:request] +
\ (pipepane ? [a:request.expanded . '; echo ' . dispatch#status_var()
\ . ' > ' . a:request.file . '.complete'] : [])))
let title = shellescape(a:request.title)
let height = get(g:, 'dispatch_tmux_height', get(g:, 'dispatch_quickfix_height', 10))
if get(a:request, 'background', 0) || (height <= 0 && dispatch#has_callback())
let cmd = 'new-window -d -n '.title
elseif has('gui_running') || empty($TMUX) || (!empty(''.session) && session !=# system('tmux display-message -p "#S"')[0:-2])
let cmd = 'new-window -n '.title
else
let cmd = 'split-window -l '.(height < 0 ? -height : height).' -d'
endif
let cmd .= ' ' . dispatch#shellescape('-P', '-t', session.':', 'exec ' . script)
let filter = 'sed'
let uname = system('uname')[0:-2]
if uname ==# 'Darwin'
let filter = '/usr/bin/sed -l'
elseif uname ==# 'Linux'
let filter .= ' -u'
endif
let filter .= " -e \"s/\r\r*$//\" -e \"s/.*\r//\""
let filter .= " -e \"s/\e\\[K//g\" "
let filter .= " -e \"s/.*\e\\[2K\e\\[[01]G//g\""
let filter .= " -e \"s/.*\e\\[?25h\e\\[0G//g\""
let filter .= " -e \"s/\e\\[[0-9;]*m//g\""
let filter .= " -e \"s/\017//g\""
let filter .= " > " . a:request.file . ""
call system('tmux ' . cmd . '|tee ' . s:make_pane .
\ (pipepane ? '|xargs -I {} tmux pipe-pane -t {} '.shellescape(filter) : ''))
let pane = s:pane_id(get(readfile(s:make_pane, '', 1), 0, ''))
if !empty(pane)
let s:waiting[pane] = a:request
return 1
endif
endfunction
function! s:pane_id(pane) abort
if a:pane =~# '\.\d\+$'
let [window, index] = split(a:pane, '\.\%(\d\+$\)\@=')
let out = system('tmux list-panes -F "#P #{pane_id}" -t '.shellescape(window))
let id = matchstr("\n".out, '\n'.index.' \+\zs%\d\+')
else
let id = system('tmux list-panes -F "#{pane_id}" -t '.shellescape(a:pane))[0:-2]
endif
return id
endfunction
function! dispatch#tmux#poll() abort
if empty(s:waiting)
return
endif
let panes = split(system('tmux list-panes -a -F "#{pane_id}"'), "\n")
for [pane, request] in items(s:waiting)
if index(panes, pane) < 0
call remove(s:waiting, pane)
call dispatch#complete(request)
endif
endfor
endfunction
function! dispatch#tmux#activate(pid) abort
let out = system('ps ewww -p '.a:pid)
let pane = matchstr(out, 'TMUX_PANE=\zs%\d\+')
if empty(pane)
return 0
endif
let session = get(g:, 'tmux_session', '')
if !empty(session)
let session = ' -t '.shellescape(session)
endif
let panes = split(system('tmux list-panes -s -F "#{pane_id}"'.session), "\n")
if index(panes, pane) >= 0
call system('tmux select-window -t '.pane.'; tmux select-pane -t '.pane)
return !v:shell_error
endif
endfunction
augroup dispatch_tmux
autocmd!
autocmd VimResized * nested if !dispatch#has_callback() | call dispatch#tmux#poll() | endif
augroup END

View File

@ -0,0 +1,89 @@
" dispatch.vim Windows strategy
if exists('g:autoloaded_dispatch_windows')
finish
endif
let g:autoloaded_dispatch_windows = 1
function! dispatch#windows#escape(str) abort
if &shellxquote ==# '"'
return '"' . substitute(a:str, '"', '""', 'g') . '"'
else
let esc = exists('+shellxescape') ? &shellxescape : '"&|<>()@^'
return &shellxquote .
\ substitute(a:str, '['.esc.']', '^&', 'g') .
\ get({'(': ')', '"(': ')"'}, &shellxquote, &shellxquote)
endif
endfunction
function! dispatch#windows#handle(request) abort
if !has('win32') || empty(v:servername)
return 0
endif
if a:request.action ==# 'make'
return dispatch#windows#make(a:request)
elseif a:request.action ==# 'start'
return dispatch#windows#start(a:request)
endif
endfunction
function! dispatch#windows#spawn(title, exec, background) abort
let extra = a:background ? ' /min' : ''
silent execute dispatch#bang('start /min cmd.exe /cstart ' .
\ '"' . substitute(a:title, '"', '', 'g') . '"' . extra . ' ' .
\ &shell . ' ' . &shellcmdflag . ' ' . dispatch#windows#escape(a:exec))
return 1
endfunction
let s:pid = "wmic process where ^(Name='WMIC.exe' AND CommandLine LIKE '\\%\\%\\%TIME\\%\\%\\%'^) get ParentProcessId | more +1 > "
function! dispatch#windows#make(request) abort
if &shellxquote ==# '"'
let exec = dispatch#prepare_make(a:request)
else
let pidfile = a:request.file.'.pid'
let exec =
\ s:pid . pidfile .
\ ' & ' . a:request.expanded .
\ ' > ' . a:request.file . ' 2>&1' .
\ ' & echo %ERRORLEVEL% > ' . a:request.file . '.complete' .
\ ' & ' . dispatch#callback(a:request)
endif
return dispatch#windows#spawn(a:request.title, exec, 1)
endfunction
function! dispatch#windows#start(request) abort
if &shellxquote ==# '"'
let exec = dispatch#prepare_start(a:request)
else
let pidfile = a:request.file.'.pid'
let pause = get({'always': ' & pause', 'never': ''},
\ get(a:request, 'wait'), ' || pause')
let exec =
\ s:pid . pidfile .
\ ' & ' . a:request.expanded .
\ pause .
\ ' & cd . > ' . a:request.file.'.complete' .
\ ' & del ' . pidfile
endif
return dispatch#windows#spawn(a:request.title, exec, a:request.background)
endfunction
function! dispatch#windows#activate(pid) abort
let tasklist_cmd = 'tasklist /fi "pid eq '.a:pid.'"'
if &shellxquote ==# '"'
let tasklist_cmd = substitute(tasklist_cmd, '"', "'", "g")
endif
if system(tasklist_cmd) !~# '==='
return 0
endif
if !exists('s:activator')
let s:activator = tempname().'.vbs'
call writefile(['WScript.CreateObject("WScript.Shell").AppActivate(WScript.Arguments(0))'], s:activator)
endif
call system('cscript //nologo '.s:activator.' '.a:pid)
return !v:shell_error
endfunction

View File

@ -0,0 +1,56 @@
" dispatch.vim X11 strategy
if exists('g:autoloaded_dispatch_x11')
finish
endif
let g:autoloaded_dispatch_x11 = 1
function! s:windowid()
if executable('xprop')
return matchstr(system("xprop -root _NET_ACTIVE_WINDOW"), '0x\x\+')
endif
endf
function! dispatch#x11#handle(request) abort
if $DISPLAY !~# '^:'
return 0
endif
let windowid = s:windowid()
if get(a:request, 'background') &&
\ (empty(windowid) || !executable('wmctrl'))
return 0
endif
if exists('g:dispatch_terminal_exec')
let terminal = g:dispatch_terminal_exec
elseif !empty($TERMINAL)
let terminal = $TERMINAL . ' -e'
elseif executable('xterm')
let terminal = 'xterm -e'
else
return 0
endif
if a:request.action ==# 'start'
return dispatch#x11#spawn(terminal, dispatch#prepare_start(a:request), a:request, windowid)
else
return 0
endif
endfunction
function! dispatch#x11#spawn(terminal, command, request, windowid) abort
let command = dispatch#set_title(a:request) . '; ' . a:command
if a:request.background
let command = 'wmctrl -i -a '. a:windowid . ';' . command
echom command
endif
call system(a:terminal . ' ' . dispatch#shellescape(&shell, &shellcmdflag, command). ' &')
return 1
endfunction
function! dispatch#x11#activate(pid) abort
let out = system('ps ewww -p '.a:pid)
let window = matchstr(out, 'WINDOWID=\zs\d\+')
if !empty(window) && executable('wmctrl')
call system('wmctrl -i -a '.window)
return !v:shell_error
endif
endfunction

226
bundle/vim-dispatch/doc/dispatch.txt vendored Normal file
View File

@ -0,0 +1,226 @@
*dispatch.txt* Asynchronous build and test dispatcher
Author: Tim Pope <http://tpo.pe/>
Repo: https://github.com/tpope/vim-dispatch
License: Same terms as Vim itself (see |license|)
INTRODUCTION *dispatch*
Leverage the power of Vim's compiler system without being constrained by
synchronicity.
COMMANDS *dispatch-commands*
*dispatch-:Make*
:Make [arguments] Using the current |:compiler| settings, dispatch a
build in the foreground. Adapter strategies vary, but
the goal is visibility without stealing focus. When
the build is complete, load the results into the
|quickfix| list and call |:cwindow|. This command is
preferred for shorter tasks like "build this file."
:Make! [arguments] Using the current compiler settings, dispatch a build
in the background. Use |:Copen| to load the results.
This command is preferred for longer tasks like "run
the entire test suite."
*dispatch-:Copen*
:Copen Load the latest build into the quickfix list and open
it with |:copen|. You may call this before the
process is finished.
:Copen! Load the latest build into the quickfix list using a
catch-all parser. This is useful when you can't tell
what went wrong.
*dispatch-:Dispatch*
:Dispatch[!] [options] {program} [arguments]
Find a compiler plugin that sets 'makeprg' to
{program} and use its 'errorformat' to dispatch a
|:Make| for the given {program} and [arguments]. If
no compiler plugin is found, the generic format
%+I%.%# is used.
:Dispatch picks a compiler by looking for either
CompilerSet makeprg={program}\ [arguments] or
CompilerSet makeprg={program} in compiler plugins.
To force a given {program} to use a given {compiler},
create ~/.vim/after/compiler/{compiler}.vim and add to
it a line like the following: >
" CompilerSet makeprg={program}
<
If you need more control, *g:dispatch_compilers* can
be set to a dictionary with commands for keys and
compiler plugins for values. Use an empty value to
skip the matched string and try again with the rest of
the command.
>
let g:dispatch_compilers = {
\ 'latex': 'tex',
\ 'bundle exec': ''}
<
You can optionally give one or more of the following
options before {program}:
-compiler=... force use of a compiler plugin
-dir=... run command in given directory
:Dispatch[!] [options] -- [arguments]
This is equivalent to |:Make| but accepts options.
*b:dispatch*
:Dispatch[!] [options] Invoke |:Dispatch| with the options, program, and
arguments found in b:dispatch. In the quickfix
window, this reruns the shown dispatch. When no other
default is found, equivalent to |:Make|.
*dispatch-:FocusDispatch*
:FocusDispatch [options] {program} [arguments]
Set a global default command for |:Dispatch| with no
arguments. Overrides |b:dispatch|.
:FocusDispatch! [options] {program} [arguments]
Set a window local default command for |:Dispatch|
with no arguments. Overrides |b:dispatch| and the
global default.
:FocusDispatch! Clear the global and window local defaults for
|:Dispatch|.
:FocusDispatch Show the task that would run when calling |:Dispatch|
with no arguments.
:0Dispatch[!] [options] Provide a range to |:Dispatch| skips any focused task
and forces |b:dispatch|.
*dispatch-:AbortDispatch*
:AbortDispatch Abort the most recent build.
:AbortDispatch {command}
Abort the most recent build of {command}.
*dispatch-:Start*
:Start [options] {command}
Start a process in a new, focused window. If
{command} and the directory for execution match a
previous :Start invocation, focus it instead, if
possible. Options:
-dir=... run command in given directory
-title=... short label for supported adapters
-wait=... when to display press enter prompt:
"always", "never", or "error"
:Start! [options] {command}
Start a process in a new, unfocused window. If
{command} and the current working directory match
previous :Start invocation, do nothing.
*b:start*
:Start[!] [options] With no arguments, |:Start| the options and command
given by |b:start|. If not set, falls back to
'shell'.
*dispatch-:Spawn*
:Spawn[!] [options] [command]
Like |:Start|, but always spawn a new process rather
than focusing an existing one. The default is always
to spawn a new 'shell'.
:0Spawn! [options]
Provide a range to |:Spawn| to spawn |b:dispatch|.
Handy for using an interactive debugger.
MAPS *dispatch-maps*
The following convenience maps are provided.
*m<CR>* |:Make|<CR>
*m<Space>* |:Make|<Space>
*m!* |:Make|!
*m?* Show 'makeprg'
*`<CR>* |:Dispatch|<CR>
*`<Space>* |:Dispatch|<Space>
*`!* |:Dispatch|!
*`?* |:FocusDispatch|<CR>
*'<CR>* |:Start|<CR>
*'<Space>* |:Start|<Space>
*'!* |:Start|!
*'?* Show |b:start|
*g'<CR>* |:Spawn|<CR>
*g'<Space>* |:Spawn|<Space>
*g'!* |:Spawn|!
*g'?* Show 'shell'
These can be disabled with
>
let g:dispatch_no_maps = 1
<
STRATEGIES *dispatch-strategies*
Strategies are listed in order of precedence. The first available one is
used. Some strategies only provide for a subset of tasks.
Disable :Make/:Dispatch or :Start/:Spawn using a given strategy by assigning
g:dispatch_no_strategyname_make or g:dispatch_no_strategyname_start,
respectively. For example, to prevent :Dispatch from ever using the Job
handler:
>
let g:dispatch_no_job_make = 1
<
Except for Tmux, which uses |VimResized|, all strategies require either |job|
support plus a file system with FIFOs (basically everything but Windows) or
|clientserver| support to do foreground makes.
Tmux ~
Foreground makes open in a small split at the bottom. The closure of the
pane triggers a |VimResized| event which loads the results into the quickfix
list.
The tmux strategy can be used from the GUI as well. Either start Vim from
inside of tmux or assign g:tmux_session. This will use a new window for
foreground makes rather than a split.
Job ~
Uses the |job| support in Vim 8 and Neovim to update the quickfix list in real
time.
GNU Screen ~
A new window is always used, since splits in GNU Screen are awkward.
Terminal ~
Uses the respective |:terminal| features of Vim and Neovim.
Windows ~
You can use either the standard cmd.exe or a cygwin shell. Both foreground
and background |:Make| invocations are started minimized to prevent focus
stealing.
iTerm ~
This strategy fires if you're in MacVim with at least one iTerm window open,
or if Vim is running in iTerm itself. Used only for |:Start|.
X11 ~
Uses g:dispatch_terminal_exec, "$TERMINAL -e", or "xterm -e". Used only for
|:Start|. Background invocations require wmctrl to be is installed (which is
used to switch the focus back to Vim).
Headless ~
Forks tasks into the background. It's working, you just can't see it. Don't
forget to check |:Copen|. The presence of this strategy means that |:Make!|
and |:Start!| will never block Vim.
Synchronous ~
When all else fails, a vanilla |:make| or |:!| is performed.
vim:tw=78:et:ft=help:norl:

107
bundle/vim-dispatch/plugin/dispatch.vim vendored Normal file
View File

@ -0,0 +1,107 @@
" Location: plugin/dispatch.vim
" Maintainer: Tim Pope <http://tpo.pe/>
" Version: 1.8
" GetLatestVimScripts: 4504 1 :AutoInstall: dispatch.vim
if exists("g:loaded_dispatch") || v:version < 700 || &compatible
finish
endif
let g:loaded_dispatch = 1
command! -bang -nargs=* -range=-1 -complete=customlist,dispatch#command_complete Dispatch
\ execute dispatch#compile_command(<bang>0, <q-args>,
\ <count> < 0 || <line1> == <line2> ? <count> : 0, '<mods>')
command! -bang -nargs=* -range=-1 -complete=customlist,dispatch#command_complete FocusDispatch
\ execute dispatch#focus_command(<bang>0, <q-args>,
\ <count> < 0 || <line1> == <line2> ? <count> : 0, '<mods>')
command! -bang -nargs=* -range=-1 -complete=customlist,dispatch#make_complete Make
\ execute dispatch#compile_command(<bang>0, '-- ' . <q-args>,
\ <count> < 0 || <line1> == <line2> ? <count> : 0, '<mods>')
command! -bang -nargs=* -range=-1 -complete=customlist,dispatch#command_complete Spawn
\ execute dispatch#spawn_command(<bang>0, <q-args>,
\ <count> < 0 || <line1> == <line2> ? <count> : 0, '<mods>')
command! -bang -nargs=* -range=-1 -complete=customlist,dispatch#command_complete Start
\ execute dispatch#start_command(<bang>0, <q-args>,
\ <count> < 0 || <line1> == <line2> ? <count> : 0, '<mods>')
command! -bang -bar Copen call dispatch#copen(<bang>0, '<mods>')
command! -bang -bar -nargs=* AbortDispatch
\ execute dispatch#abort_command(<bang>0, <q-args>)
function! s:map(mode, lhs, rhs, ...) abort
let flags = (a:0 ? a:1 : '') . (a:rhs =~# '^<Plug>' ? '' : '<script>')
let head = a:lhs
let tail = ''
let keys = get(g:, a:mode.'remap', {})
if type(keys) == type([])
return
endif
while !empty(head)
if has_key(keys, head)
let head = keys[head]
if empty(head)
return
endif
break
endif
let tail = matchstr(head, '<[^<>]*>$\|.$') . tail
let head = substitute(head, '<[^<>]*>$\|.$', '', '')
endwhile
exe a:mode.'map' flags head.tail a:rhs
endfunction
nmap <script> <SID>:. :<C-R>=getcmdline() =~ ',' ? "\0250" : ""<CR>
if !get(g:, 'dispatch_no_maps')
call s:map('n', 'm<CR>', '<SID>:.Make<CR>')
call s:map('n', 'm<Space>', '<SID>:.Make<Space>')
call s:map('n', 'm!', '<SID>:.Make!')
call s:map('n', 'm?', ':<C-U>echo ":Dispatch" dispatch#make_focus(v:count > 1 ? 0 : v:count ? line(".") : -1)<CR>', '<silent>')
call s:map('n', '`<CR>', '<SID>:.Dispatch<CR>')
call s:map('n', '`<Space>', '<SID>:.Dispatch<Space>')
call s:map('n', '`!', '<SID>:.Dispatch!')
call s:map('n', '`?', '<SID>:.FocusDispatch<CR>')
call s:map('n', '''<CR>', '<SID>:.Start<CR>')
call s:map('n', '''<Space>', '<SID>:.Start<Space>')
call s:map('n', '''!', '<SID>:.Start!')
call s:map('n', '''?', ':<C-U>echo ":Start" dispatch#start_focus(v:count > 1 ? 0 : v:count ? line(".") : -1)<CR>', '<silent>')
call s:map('n', 'g''<CR>', '<SID>:.Spawn<CR>')
call s:map('n', 'g''<Space>', '<SID>:.Spawn<Space>')
call s:map('n', 'g''!', '<SID>:.Spawn!')
call s:map('n', 'g''?', ':<C-U>echo ":Spawn" dispatch#spawn_focus(v:count > 1 ? 0 : v:count ? line(".") : -1)<CR>', '<silent>')
call s:map('n', 'g`<CR>', '<SID>:.Spawn<CR>')
call s:map('n', 'g`<Space>', '<SID>:.Spawn<Space>')
call s:map('n', 'g`!', '<SID>:.Spawn!')
call s:map('n', 'g`?', ':<C-U>echo ":Spawn" dispatch#spawn_focus(v:count > 1 ? 0 : v:count ? line(".") : -1)<CR>', '<silent>')
endif
function! DispatchComplete(id) abort
return dispatch#complete(a:id)
endfunction
if !exists('g:dispatch_handlers')
let g:dispatch_handlers = [
\ 'tmux',
\ 'job',
\ 'screen',
\ 'terminal',
\ 'windows',
\ 'iterm',
\ 'x11',
\ 'headless',
\ ]
endif
augroup dispatch
autocmd!
autocmd QuickfixCmdPre,QuickfixCmdPost * "
autocmd FileType qf
\ if &buftype ==# 'quickfix' && empty(getloclist(winnr())) && get(w:, 'quickfix_title') =~# '^:noautocmd cgetfile\>\|^:\d*Dispatch\>' |
\ call dispatch#quickfix_init() |
\ endif
augroup END

8118
bundle/vim-fugitive/autoload/fugitive.vim vendored Normal file

File diff suppressed because it is too large Load Diff

730
bundle/vim-fugitive/doc/fugitive.txt vendored Normal file
View File

@ -0,0 +1,730 @@
*fugitive.txt* A Git wrapper so awesome, it should be illegal
Author: Tim Pope <http://tpo.pe/>
License: Same terms as Vim itself (see |license|)
This plugin is only available if 'compatible' is not set.
INTRODUCTION *fugitive*
Whenever you edit a file from a Git repository, a set of commands is defined
that serve as a gateway to Git.
COMMANDS *fugitive-commands*
These commands are local to the buffers in which they work (generally, buffers
that are part of Git repositories).
*fugitive-:G*
:G [args] Same as :Git, but two characters shorter.
*:Git*
:Git {args} Run an arbitrary git command and display any output.
On UNIX this uses a pty and on other platforms it uses
a pipe, which will cause some behavior differences
such as the absence of progress bars. Any file the
command edits (for example, a commit message) will be
loaded into a split window. Closing that window will
resume running the command. A few Git subcommands
have different behavior; these are documented below.
*:Git!*
:Git! {args} Run an arbitrary git command in the background and
stream the output to the preview window. Requires a
Vim with |setbufline()|. Press CTRL-D during an
interactive :Git invocation to switch to this mode
retroactively.
*:Git_--paginate* *:Git_-p*
:Git --paginate {args} Run an arbitrary git command, capture output to a temp
:Git -p {args} file, and |:split| that temp file. Pass ++curwin as
the first argument to |:edit| the temp file instead.
A temp file is always used for commands like diff and
log that typically uses a pager, and for any command
that has the pager.<cmd> Git configuration option set.
:{range}Git! --paginate {args}
:{range}Git! -p {args} Run an arbitrary git command, and insert the output
after {range} in the current buffer.
*fugitive-summary*
:Git With no arguments, bring up a summary window vaguely
akin to git-status. Press g? or see |fugitive-maps|
for usage.
*:Git_blame*
:Git blame [flags] Run git-blame [flags] on the current file and open the
results in a scroll-bound vertical split. The
following maps, which work on the cursor line commit
where sensible, are provided:
g? show this help
A resize to end of author column
C resize to end of commit column
D resize to end of date/time column
gq close blame, then |:Gedit| to return to work
tree version
<CR> close blame, and jump to patch that added line
(or directly to blob for boundary commit)
o jump to patch or blob in horizontal split
O jump to patch or blob in new tab
p jump to patch or blob in preview window
- reblame at commit
~ reblame at commit~[count]
P reblame at commit^[count]
*g:fugitive_dynamic_colors*
In the GUI or a 256 color terminal, commit hashes will
highlighted in different colors. To disable this:
>
let g:fugitive_dynamic_colors = 0
<
:[range]Git blame [...] If a range is given, just that part of the file will
:Git blame [...] {file} be blamed, and a horizontal split without
scrollbinding is used. You can also give an arbitrary
filename.
*:Git_difftool*
:Git[!] difftool [args] Invoke `git diff [args]` and load the changes into the
quickfix list. Each changed hunk gets a separate
quickfix entry unless you pass an option like
--name-only or --name-status. Jumps to the first
change unless [!] is given.
:Git difftool -y [args] Invoke `git diff [args]`, open each changed file in a
new tab, and invoke |:Gdiffsplit!| against the
appropriate commit.
*:Git_mergetool*
:Git mergetool [args] Like |:Git_difftool|, but target merge conflicts.
Wrappers for Vim built-ins ~
These all directly map onto a built-in Vim command, and generally have names
that prepend "G" to the command they are wrapping. For example, :Ggrep is G
plus |:grep|.
*:Ggrep* *:Git_grep*
:Ggrep[!] [args] An approximation of |:grep|[!] with git-grep as
:Git[!] grep -O [args] 'grepprg'.
:Ggrep[!] --quiet [args]
:Ggrep[!] -q [args] Like |:Ggrep|, but instead of displaying output, open
the quickfix list.
*:Glgrep*
:Glgrep[!] [args] :Ggrep but for |:lgrep|.
:0Git[!] grep -O [args]
*:Gclog*
:Gclog[!] [args] Use git-log [args] to load the commit history into the
|quickfix| list. Jumps to the first commit unless [!]
is given. This command wraps |:cfile|.
The quickfix list can be awkward for many use cases
and exhibits extremely poor performance with larger
data sets. Consider using |:Git| log --oneline
instead.
:{range}Gclog[!] [args] Use git-log -L to load previous revisions of the given
range of the current file into the |quickfix| list.
The cursor is positioned on the first line of the
first diff hunk for each commit. Use :0Gclog to
target the entire file.
*:Gllog*
:Gllog [args] Like |:Gclog|, but use the location list instead of the
|quickfix| list.
*:Gcd*
:Gcd [directory] |:cd| relative to the repository.
*:Glcd*
:Glcd [directory] |:lcd| relative to the repository.
*:Gedit* *fugitive-:Ge*
:Gedit [object] |:edit| a |fugitive-object|.
*:Gsplit*
:Gsplit [object] |:split| a |fugitive-object|.
*:Gvsplit*
:Gvsplit [object] |:vsplit| a |fugitive-object|.
*:Gtabedit*
:Gtabedit [object] |:tabedit| a |fugitive-object|.
*:Gpedit*
:Gpedit [object] |:pedit| a |fugitive-object|.
*:Gdrop*
:Gdrop [object] |:drop| a |fugitive-object|.
*:Gread* *fugitive-:Gr*
:Gread [object] Empty the buffer and |:read| a |fugitive-object|.
When the argument is omitted, this is similar to
git-checkout on a work tree file or git-add on a stage
file, but without writing anything to disk.
:{range}Gread [object] |:read| in a |fugitive-object| after {range}.
*:Gwrite* *fugitive-:Gw*
:Gwrite Write to the current file's path and stage the results.
When run in a work tree file, it is effectively git
add. Elsewhere, it is effectively git-checkout. A
great deal of effort is expended to behave sensibly
when the work tree or index version of the file is
open in another buffer.
:Gwrite {path} You can give |:Gwrite| an explicit path of where in
the work tree to write. You can also give a path like
:0:foo.txt or :0:% to write to just that stage in
the index.
*:Gwq*
:Gwq [path] Like |:Gwrite| followed by |:quit| if the write
succeeded.
:Gwq! [path] Like |:Gwrite|! followed by |:quit|! if the write
succeeded.
*:Gdiffsplit*
:Gdiffsplit [object] Perform a |vimdiff| against the given file, or if a
commit is given, the current file in that commit.
With no argument, the version in the index or work
tree is used, and the work tree version is always
placed to the right or bottom, depending on available
width. Use Vim's |do| and |dp| to stage and unstage
changes.
*:Gdiffsplit!*
:Gdiffsplit! Diff against any and all direct ancestors, retaining
focus on the current window. During a merge conflict,
this is a three-way diff against the "ours" and
"theirs" ancestors. Additional d2o and d3o maps are
provided to obtain the hunk from the "ours" or
"theirs" ancestor, respectively.
:Gdiffsplit! {object} Like |:Gdiffsplit|, but retain focus on the current
window.
*:Gvdiffsplit*
:Gvdiffsplit [object] Like |:Gdiffsplit|, but always split vertically.
*:Ghdiffsplit*
:Gdiffsplit ++novertical [object]
:Ghdiffsplit [object] Like |:Gdiffsplit|, but with "vertical" removed from
'diffopt'. The split will still be vertical if
combined with |:vertical|.
Other commands ~
These do not directly correspond to any built-in Vim command, and have a
capital letter after the "G" to convey this. For example, the file move
operation has nothing to do with the |:move| built-in, so it is named :GMove,
not :Gmove.
*:GMove*
:GMove {destination} Wrapper around git-mv that renames the buffer
afterward. Add a ! to pass -f.
*:GRename*
:GRename {destination} Like |:GMove| but operates relative to the parent
directory of the current file.
*:GDelete*
:GDelete Wrapper around git-rm that deletes the buffer
afterward. When invoked in an index file, --cached is
passed. Add a ! to pass -f and forcefully discard the
buffer.
*:GRemove* *:GUnlink*
:GRemove Like |:GDelete|, but keep the (now empty) buffer around.
:GUnlink
*:GBrowse*
:GBrowse Open the current file, blob, tree, commit, or tag
in your browser at the upstream hosting provider.
Upstream providers can be added by installing an
appropriate Vim plugin. For example, GitHub can be
supported by installing rhubarb.vim, available at
<https://github.com/tpope/vim-rhubarb>.
:GBrowse {object} Like :GBrowse, but for a given |fugitive-object|.
:{range}GBrowse [args] Appends an anchor to the URL that emphasizes the
selected lines. This also forces the URL to include a
commit rather than a branch name so it remains valid
if the file changes. You can give a range of "0" to
force this behavior without including an anchor.
:GBrowse [...]@{remote} Force using the given remote rather than the remote
for the current branch. The remote is used to
determine which upstream repository to link to.
:GBrowse {url} Open an arbitrary URL in your browser.
:[range]GBrowse! [args] Like :GBrowse, but put the URL on the clipboard rather
than opening it.
MAPS *fugitive-maps*
These maps are available in both the |fugitive-summary| buffer and Fugitive
object buffers, although not all maps make sense in all buffers. Mappings
that operate on the file or hunk under the cursor are generally available in
visual mode to operate on multiple files or partial hunks.
*fugitive-staging-maps*
Staging/unstaging maps ~
*fugitive_s*
s Stage (add) the file or hunk under the cursor.
*fugitive_u*
u Unstage (reset) the file or hunk under the cursor.
*fugitive_-*
- Stage or unstage the file or hunk under the cursor.
*fugitive_U*
U Unstage everything.
*fugitive_X*
X Discard the change under the cursor. This uses
`checkout` or `clean` under the hood. A command is
echoed that shows how to undo the change. Consult
`:messages` to see it again. During a merge conflict,
use 2X to call `checkout --ours` or 3X to call
`checkout --theirs` .
*fugitive_=*
= Toggle an inline diff of the file under the cursor.
*fugitive_>*
> Insert an inline diff of the file under the cursor.
*fugitive_<*
< Remove the inline diff of the file under the cursor.
*fugitive_gI*
gI Open .git/info/exclude in a split and add the file
under the cursor. Use a count to open .gitignore.
*fugitive_I*
I Invoke |:Git| add --patch or reset --patch on the file
P under the cursor. On untracked files, this instead
calls |:Git| add --intent-to-add.
*fugitive_d*
Diff maps ~
*fugitive_dp*
dp Invoke |:Git| diff on the file under the cursor.
Deprecated in favor of inline diffs.
*fugitive_dd*
dd Perform a |:Gdiffsplit| on the file under the cursor.
*fugitive_dv*
dv Perform a |:Gvdiffsplit| on the file under the cursor.
*fugitive_ds* *fugitive_dh*
ds Perform a |:Ghdiffsplit| on the file under the cursor.
dh
*fugitive_dq*
dq Close all but one diff buffer, and |:diffoff|! the
last one.
*fugitive_d?*
d? Show this help.
*fugitive-navigation-maps*
Navigation maps ~
*fugitive_<CR>*
<CR> Open the file or |fugitive-object| under the cursor.
In a blob, this and similar maps jump to the patch
from the diff where this was added, or where it was
removed if a count was given. If the line is still in
the work tree version, passing a count takes you to
it.
*fugitive_o*
o Open the file or |fugitive-object| under the cursor in
a new split.
*fugitive_gO*
gO Open the file or |fugitive-object| under the cursor in
a new vertical split.
*fugitive_O*
O Open the file or |fugitive-object| under the cursor in
a new tab.
*fugitive_p*
p Open the file or |fugitive-object| under the cursor in
a preview window. In the status buffer, 1p is
required to bypass the legacy usage instructions.
*fugitive_~*
~ Open the current file in the [count]th first ancestor.
*fugitive_P*
P Open the current file in the [count]th parent.
*fugitive_C*
C Open the commit containing the current file.
*fugitive_CTRL-P* *fugitive_(*
( Jump to the previous file, hunk, or revision.
*fugitive_CTRL-N* *fugitive_)*
) Jump to the next file, hunk, or revision.
*fugitive_[c*
[c Jump to previous hunk, expanding inline diffs
automatically. (This shadows the Vim built-in |[c|
that provides a similar operation in |diff| mode.)
*fugitive_]c*
]c Jump to next hunk, expanding inline diffs
automatically. (This shadows the Vim built-in |]c|
that provides a similar operation in |diff| mode.)
*fugitive_[/* *fugitive_[m*
[/ Jump to previous file, collapsing inline diffs
[m automatically. (Mnemonic: "/" appears in filenames,
"m" appears in "filenames".)
*fugitive_]/* *fugitive_]m*
]/ Jump to next file, collapsing inline diffs
]m automatically. (Mnemonic: "/" appears in filenames,
"m" appears in "filenames".)
*fugitive_i*
i Jump to the next file or hunk, expanding inline diffs
automatically.
*fugitive_[[*
[[ Jump [count] sections backward.
*fugitive_]]*
]] Jump [count] sections forward.
*fugitive_[]*
[] Jump [count] section ends backward.
*fugitive_][*
][ Jump [count] section ends forward.
*fugitive_star*
* On the first column of a + or - diff line, search for
the corresponding - or + line. Otherwise, defer to
built-in |star|.
*fugitive_#*
# Same as "*", but search backward.
*fugitive_gu*
gu Jump to file [count] in the "Untracked" or "Unstaged"
section.
*fugitive_gU*
gU Jump to file [count] in the "Unstaged" section.
*fugitive_gs*
gs Jump to file [count] in the "Staged" section.
*fugitive_gp*
gp Jump to file [count] in the "Unpushed" section.
*fugitive_gP*
gP Jump to file [count] in the "Unpulled" section.
*fugitive_gr*
gr Jump to file [count] in the "Rebasing" section.
*fugitive_gi*
gi Open .git/info/exclude in a split. Use a count to
open .gitignore.
*fugitive_c*
Commit maps ~
cc Create a commit.
ca Amend the last commit and edit the message.
ce Amend the last commit without editing the message.
cw Reword the last commit.
cvc Create a commit with -v.
cva Amend the last commit with -v
cf Create a `fixup!` commit for the commit under the
cursor.
cF Create a `fixup!` commit for the commit under the
cursor and immediately rebase it.
cs Create a `squash!` commit for the commit under the
cursor.
cS Create a `squash!` commit for the commit under the
cursor and immediately rebase it.
cA Create a `squash!` commit for the commit under the
cursor and edit the message.
c<Space> Populate command line with ":Git commit ".
*fugitive_cr*
crc Revert the commit under the cursor.
crn Revert the commit under the cursor in the index and
work tree, but do not actually commit the changes.
cr<Space> Populate command line with ":Git revert ".
*fugitive_cm*
cm<Space> Populate command line with ":Git merge ".
c? Show this help.
*fugitive_cb*
*fugitive_co*
Checkout/branch maps ~
coo Check out the commit under the cursor.
cb<Space> Populate command line with ":Git branch ".
co<Space> Populate command line with ":Git checkout ".
cb? Show this help.
co?
*fugitive_cz*
Stash maps ~
czz Push stash. Pass a [count] of 1 to add
`--include-untracked` or 2 to add `--all`.
czw Push stash of worktree. Like `czz` with
`--keep-index`.
czA Apply topmost stash, or stash@{count}.
cza Apply topmost stash, or stash@{count}, preserving the
index.
czP Pop topmost stash, or stash@{count}.
czp Pop topmost stash, or stash@{count}, preserving the
index.
cz<Space> Populate command line with ":Git stash ".
cz? Show this help.
*fugitive_r*
Rebase maps ~
ri Perform an interactive rebase. Uses ancestor of
u commit under cursor as upstream if available.
rf Perform an autosquash rebase without editing the todo
list. Uses ancestor of commit under cursor as
upstream if available.
ru Perform an interactive rebase against @{upstream}.
rp Perform an interactive rebase against @{push}.
rr Continue the current rebase.
rs Skip the current commit and continue the current
rebase.
ra Abort the current rebase.
re Edit the current rebase todo list.
rw Perform an interactive rebase with the commit under
the cursor set to `reword`.
rm Perform an interactive rebase with the commit under
the cursor set to `edit`.
rd Perform an interactive rebase with the commit under
the cursor set to `drop`.
r<Space> Populate command line with ":Git rebase ".
r? Show this help.
*fugitive-misc-maps*
Miscellaneous maps ~
*fugitive_gq* *fugitive_q*
gq Close the status buffer.
*fugitive_.*
. Start a |:| command line with the file under the
cursor prepopulated.
*fugitive_g?*
g? Show help for |fugitive-maps|.
*fugitive-global-maps*
Global maps ~
*fugitive_c_CTRL-R_CTRL-G*
<C-R><C-G> On the command line, recall the path to the current
|fugitive-object| (that is, a representation of the
object recognized by |:Gedit|).
*fugitive_y_CTRL-G*
["x]y<C-G> Yank the path to the current |fugitive-object|.
*g:fugitive_no_maps*
Global maps can be disabled with the g:fugitive_no_maps option.
>
let g:fugitive_no_maps = 1
<
SPECIFYING OBJECTS *fugitive-object* *fugitive-revision*
Fugitive objects are either work tree files or Git revisions as defined in the
"SPECIFYING REVISIONS" section in the git-rev-parse man page, with expansions
inspired by |cmdline-special| layered on top. For commands that accept an
optional object, the default is the file in the index for work tree files and
the work tree file for everything else. Example objects follow.
Object Meaning ~
@ The commit referenced by @ aka HEAD
master The commit referenced by master
master^ The parent of the commit referenced by master
master...other The merge base of master and other
master: The tree referenced by master
./master The file named master in the working directory
:(top)master The file named master in the work tree
Makefile The file named Makefile in the work tree
@^:Makefile The file named Makefile in the parent of HEAD
:Makefile The file named Makefile in the index (writable)
@~2:% The current file in the grandparent of HEAD
:% The current file in the index
:1:% The current file's common ancestor during a conflict
:2:# The alternate file in the target branch during a conflict
:3:#5 The file from buffer #5 in the merged branch during a conflict
! The commit owning the current file
!:Makefile The file named Makefile in the commit owning the current file
!3^2 The second parent of the commit owning buffer #3
.git/config The repo config file
: The |fugitive-summary| buffer
- A temp file containing the last |:Git| invocation's output
<cfile> The file or commit under the cursor
STATUSLINE *fugitive-statusline*
*FugitiveStatusline()* *fugitive#statusline()*
Add %{FugitiveStatusline()} to your statusline to get an indicator including
the current branch and the currently edited file's commit. If you don't have
a statusline, this one matches the default when 'ruler' is set:
>
set statusline=%<%f\ %h%m%r%{FugitiveStatusline()}%=%-14.(%l,%c%V%)\ %P
<
AUTOCOMMANDS *fugitive-autocommands*
A handful of |User| |autocommands| are provided to allow extending and
overriding Fugitive behaviors. Example usage:
>
autocmd User FugitiveBlob,FugitiveStageBlob call s:BlobOverrides()
<
*User_FugitiveTag*
FugitiveTag After loading a tag object.
*User_FugitiveCommit*
FugitiveCommit After loading a commit object.
*User_FugitiveTree*
FugitiveTree After loading a tree (directory) object.
*User_FugitiveBlob*
FugitiveBlob After loading a committed blob (file) object.
*User_FugitiveObject*
FugitiveObject After loading any of the 4 above buffer types.
*User_FugitiveStageBlob*
FugitiveStageBlob After loading a staged blob (file) object. These
buffers are 'modifiable' and oftentimes don't want the
same behavior as the other buffer types.
*User_FugitiveIndex*
FugitiveIndex After loading the |fugitive-summary| buffer.
*User_FugitivePager*
FugitivePager After loading a temp file created by a command like
:Git --paginate or :Git blame.
*User_FugitiveEditor*
FugitiveEditor After a :Git command (e.g., :Git commit) edits a file
(e.g., the commit message).
*User_FugitiveChanged*
FugitiveChanged After any event which can potentially change the
repository, for example, any invocation of |:Git|.
Originally intended for expiring caches, but can have
other uses.
API *fugitive-api*
Officially supported functions are documented inline in plugin/fugitive.vim.
DEPRECATIONS *fugitive-deprecated*
The following commands are deprecated in favor of replacements that adhere to
a new naming scheme. Remember that |:Git| can be shortened to |:G|, so
replacements using it are just one space character longer than the legacy
version.
*:Gremove* Superseded by |:GRemove|.
*:Gdelete* Superseded by |:GDelete|.
*:Gmove* Superseded by |:GMove|.
*:Grename* Superseded by |:GRename|.
*:Gbrowse* Superseded by |:GBrowse|.
*:Gdiff* Superseded by |:Gdiffsplit|
*:Gsdiff* Superseded by |:Ghdiffsplit|
*:Gvdiff* Superseded by |:Gvdiffsplit| or |:vert| |:Gdiffsplit|.
*:Gblame* Superseded by |:Git_blame|.
*:Gcommit* Superseded by |:Git| commit.
*:Gmerge* Superseded by |:Git| merge and |:Git_mergetool|.
*:Gpull* Superseded by |:Git| pull.
*:Grebase* Superseded by |:Git| rebase.
*:Grevert* Superseded by |:Git| revert.
*:Gpush* Superseded by |:Git| push.
*:Gfetch* Superseded by |:Git| fetch.
*:Glog* Superseded by |:Gclog|.
*:Gstatus* Superseded by |:Git| (with no arguments).
*:Gsplit!* Superseded by |:Git_--paginate|.
*:Gvsplit!* Superseded by :vert Git --paginate.
*:Gtabsplit!* Superseded by :tab Git --paginate.
*:Gpedit!* Superseded by :Git! --paginate.
*User_Fugitive*
Fugitive used to support `:autocmd User Fugitive` to run an autocommand after
loading any buffer belonging to a Git repository, but this has been phased
out. Instead, one can leverage regular autocommand events like |BufNewFile|
and |BufReadPost|, and check !empty(FugitiveGitDir()) to confirm Fugitive has
found a repository. See also |fugitive-autocommands| for other, more
selective events.
ABOUT *fugitive-about*
Grab the latest version or report a bug on GitHub:
https://github.com/tpope/vim-fugitive
vim:tw=78:et:ft=help:norl:

View File

@ -0,0 +1 @@
autocmd BufReadPost *.fugitiveblame setfiletype fugitiveblame

View File

@ -0,0 +1,6 @@
if exists("b:did_ftplugin") || !exists("*FugitiveGitDir")
finish
endif
let b:did_ftplugin = 1
call fugitive#BlameFileType()

748
bundle/vim-fugitive/plugin/fugitive.vim vendored Normal file
View File

@ -0,0 +1,748 @@
" fugitive.vim - A Git wrapper so awesome, it should be illegal
" Maintainer: Tim Pope <http://tpo.pe/>
" Version: 3.7
" GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim
if exists('g:loaded_fugitive')
finish
endif
let g:loaded_fugitive = 1
let s:bad_git_dir = '/$\|^fugitive:'
" FugitiveGitDir() returns the detected Git dir for the given buffer number,
" or the current buffer if no argument is passed. This will be an empty
" string if no Git dir was found. Use !empty(FugitiveGitDir()) to check if
" Fugitive is active in the current buffer. Do not rely on this for direct
" filesystem access; use FugitiveFind('.git/whatever') instead.
function! FugitiveGitDir(...) abort
if v:version < 704
return ''
elseif !a:0 || type(a:1) == type(0) && a:1 < 0 || a:1 is# get(v:, 'true', -1)
if exists('g:fugitive_event')
return g:fugitive_event
endif
let dir = get(b:, 'git_dir', '')
if empty(dir) && (empty(bufname('')) || &buftype =~# '^\%(nofile\|acwrite\|quickfix\|terminal\|prompt\)$')
return FugitiveExtractGitDir(getcwd())
elseif (!exists('b:git_dir') || b:git_dir =~# s:bad_git_dir) && &buftype =~# '^\%(nowrite\)\=$'
let b:git_dir = FugitiveExtractGitDir(bufnr(''))
return b:git_dir
endif
return dir =~# s:bad_git_dir ? '' : dir
elseif type(a:1) == type(0) && a:1 isnot# 0
if a:1 == bufnr('') && (!exists('b:git_dir') || b:git_dir =~# s:bad_git_dir) && &buftype =~# '^\%(nowrite\)\=$'
let b:git_dir = FugitiveExtractGitDir(a:1)
endif
let dir = getbufvar(a:1, 'git_dir')
return dir =~# s:bad_git_dir ? '' : dir
elseif type(a:1) == type('')
return substitute(s:Slash(a:1), '/$', '', '')
elseif type(a:1) == type({})
return get(a:1, 'fugitive_dir', get(a:1, 'git_dir', ''))
else
return ''
endif
endfunction
" FugitiveReal() takes a fugitive:// URL and returns the corresponding path in
" the work tree. This may be useful to get a cleaner path for inclusion in
" the statusline, for example. Note that the file and its parent directories
" are not guaranteed to exist.
"
" This is intended as an abstract API to be used on any "virtual" path. For a
" buffer named foo://bar, check for a function named FooReal(), and if it
" exists, call FooReal("foo://bar").
function! FugitiveReal(...) abort
let file = a:0 ? a:1 : @%
if type(file) ==# type({})
let dir = FugitiveGitDir(file)
let tree = s:Tree(dir)
return s:VimSlash(empty(tree) ? dir : tree)
elseif file =~# '^\a\a\+:' || a:0 > 1
return call('fugitive#Real', [file] + a:000[1:-1])
elseif file =~# '^/\|^\a:\|^$'
return file
else
return fnamemodify(file, ':p' . (file =~# '[\/]$' ? '' : ':s?[\/]$??'))
endif
endfunction
" FugitiveFind() takes a Fugitive object and returns the appropriate Vim
" buffer name. You can use this to generate Fugitive URLs ("HEAD:README") or
" to get the absolute path to a file in the Git dir (".git/HEAD"), the common
" dir (".git/config"), or the work tree (":(top)Makefile").
"
" An optional second argument provides the Git dir, or the buffer number of a
" buffer with a Git dir. The default is the current buffer.
function! FugitiveFind(...) abort
if a:0 && (type(a:1) ==# type({}) || type(a:1) ==# type(0))
return call('fugitive#Find', a:000[1:-1] + [FugitiveGitDir(a:1)])
else
return fugitive#Find(a:0 ? a:1 : bufnr(''), FugitiveGitDir(a:0 > 1 ? a:2 : -1))
endif
endfunction
" FugitiveParse() takes a fugitive:// URL and returns a 2 element list
" containing an object name ("commit:file") and the Git dir. It's effectively
" the inverse of FugitiveFind().
function! FugitiveParse(...) abort
let path = s:Slash(a:0 ? a:1 : @%)
if path !~# '^fugitive://'
return ['', '']
endif
let [rev, dir] = fugitive#Parse(path)
if !empty(dir)
return [rev, dir]
endif
throw 'fugitive: invalid Fugitive URL ' . path
endfunction
" FugitiveGitVersion() queries the version of Git in use. Pass up to 3
" arguments to return a Boolean of whether a certain minimum version is
" available (FugitiveGitVersion(2,3,4) checks for 2.3.4 or higher) or no
" arguments to get a raw string.
function! FugitiveGitVersion(...) abort
return call('fugitive#GitVersion', a:000)
endfunction
" FugitiveResult() returns an object encapsulating the result of the most
" recent :Git command. Will be empty if no result is available. During a
" User FugitiveChanged event, this is guaranteed to correspond to the :Git
" command that triggered the event, or be empty if :Git was not the trigger.
" Pass in the name of a temp buffer to get the result object for that command
" instead. Contains the following keys:
"
" * "args": List of command arguments, starting with the subcommand. Will be
" empty for usages like :Git --help.
" * "git_dir": Git dir of the relevant repository.
" * "exit_status": The integer exit code of the process.
" * "flags": Flags passed directly to Git, like -c and --help.
" * "file": Path to file containing command output. Not guaranteed to exist,
" so verify with filereadable() before trying to access it.
function! FugitiveResult(...) abort
return call('fugitive#Result', a:000)
endfunction
" FugitiveExecute() runs Git with a list of arguments and returns a dictionary
" with the following keys:
"
" * "exit_status": The integer exit code of the process.
" * "stdout": The stdout produced by the process, as a list of lines.
" * "stderr": The stdout produced by the process, as a list of lines.
"
" An optional second argument provides the Git dir, or the buffer number of a
" buffer with a Git dir. The default is the current buffer.
"
" An optional final argument is a callback Funcref, for asynchronous
" execution.
function! FugitiveExecute(args, ...) abort
return call('fugitive#Execute', [a:args] + a:000)
endfunction
" FugitiveShellCommand() turns an array of arugments into a Git command string
" which can be executed with functions like system() and commands like :!.
" Integer arguments will be treated as buffer numbers, and the appropriate
" relative path inserted in their place.
"
" An optional second argument provides the Git dir, or the buffer number of a
" buffer with a Git dir. The default is the current buffer.
function! FugitiveShellCommand(...) abort
return call('fugitive#ShellCommand', a:000)
endfunction
" FugitiveConfig() get returns an opaque structure that can be passed to other
" FugitiveConfig functions in lieu of a Git directory. This can be faster
" when performing multiple config queries. Do not rely on the internal
" structure of the return value as it is not guaranteed. If you want a full
" dictionary of every config value, use FugitiveConfigGetRegexp('.*').
"
" An optional argument provides the Git dir, or the buffer number of a
" buffer with a Git dir. The default is the current buffer. Pass a blank
" string to limit to the global config.
function! FugitiveConfig(...) abort
return call('fugitive#Config', a:000)
endfunction
" FugitiveConfigGet() retrieves a Git configuration value. An optional second
" argument can be either the object returned by FugitiveConfig(), or a Git
" dir or buffer number to be passed along to FugitiveConfig().
function! FugitiveConfigGet(name, ...) abort
return get(call('FugitiveConfigGetAll', [a:name] + (a:0 ? [a:1] : [])), 0, get(a:, 2, ''))
endfunction
" FugitiveConfigGetAll() is like FugitiveConfigGet() but returns a list of
" all values.
function! FugitiveConfigGetAll(name, ...) abort
return call('fugitive#ConfigGetAll', [a:name] + a:000)
endfunction
" FugitiveConfigGetRegexp() retrieves a dictionary of all configuration values
" with a key matching the given pattern. Like git config --get-regexp, but
" using a Vim regexp. Second argument has same semantics as
" FugitiveConfigGet().
function! FugitiveConfigGetRegexp(pattern, ...) abort
return call('fugitive#ConfigGetRegexp', [a:pattern] + a:000)
endfunction
" FugitiveRemoteUrl() retrieves the remote URL for the given remote name,
" defaulting to the current branch's remote or "origin" if no argument is
" given. Similar to `git remote get-url`, but also attempts to resolve HTTP
" redirects and SSH host aliases.
"
" An optional second argument provides the Git dir, or the buffer number of a
" buffer with a Git dir. The default is the current buffer.
function! FugitiveRemoteUrl(...) abort
return call('fugitive#RemoteUrl', a:000)
endfunction
" FugitiveRemote() returns a data structure parsed from the remote URL.
" For example, for remote URL "https://me@example.com:1234/repo.git", the
" returned dictionary will contain the following:
"
" * "scheme": "https"
" * "authority": "user@example.com:1234"
" * "path": "/repo.git" (for SSH URLs this may be a relative path)
" * "pathname": "/repo.git" (always coerced to absolute path)
" * "host": "example.com:1234"
" * "hostname": "example.com"
" * "port": "1234"
" * "user": "me"
" * "path": "/repo.git"
" * "url": "https://me@example.com:1234/repo.git"
function! FugitiveRemote(...) abort
return call('fugitive#Remote', a:000)
endfunction
" FugitiveDidChange() triggers a FugitiveChanged event and reloads the summary
" buffer for the current or given buffer number's repository. You can also
" give the result of a FugitiveExecute() and that context will be made
" available inside the FugitiveChanged() event.
"
" Passing the special argument 0 (the number zero) softly expires summary
" buffers for all repositories. This can be used after a call to system()
" with unclear implications.
function! FugitiveDidChange(...) abort
return call('fugitive#DidChange', a:000)
endfunction
" FugitiveHead() retrieves the name of the current branch. If the current HEAD
" is detached, FugitiveHead() will return the empty string, unless the
" optional argument is given, in which case the hash of the current commit
" will be truncated to the given number of characters.
"
" An optional second argument provides the Git dir, or the buffer number of a
" buffer with a Git dir. The default is the current buffer.
function! FugitiveHead(...) abort
if a:0 && (type(a:1) ==# type({}) || type(a:1) ==# type('') && a:1 !~# '^\d\+$')
let dir = FugitiveGitDir(a:1)
let arg = get(a:, 2, 0)
elseif a:0 > 1
let dir = FugitiveGitDir(a:2)
let arg = a:1
else
let dir = FugitiveGitDir()
let arg = get(a:, 1, 0)
endif
if empty(dir)
return ''
endif
return fugitive#Head(arg, dir)
endfunction
function! FugitivePath(...) abort
if a:0 > 2 && type(a:1) ==# type({})
return fugitive#Path(a:2, a:3, FugitiveGitDir(a:1))
elseif a:0 && type(a:1) ==# type({})
return FugitiveReal(a:0 > 1 ? a:2 : @%)
elseif a:0 > 1
return fugitive#Path(a:1, a:2, FugitiveGitDir(a:0 > 2 ? a:3 : -1))
else
return FugitiveReal(a:0 ? a:1 : @%)
endif
endfunction
function! FugitiveStatusline(...) abort
if empty(FugitiveGitDir(bufnr('')))
return ''
endif
return fugitive#Statusline()
endfunction
let s:resolved_git_dirs = {}
function! FugitiveActualDir(...) abort
let dir = call('FugitiveGitDir', a:000)
if empty(dir)
return ''
endif
if !has_key(s:resolved_git_dirs, dir)
let s:resolved_git_dirs[dir] = s:ResolveGitDir(dir)
endif
return empty(s:resolved_git_dirs[dir]) ? dir : s:resolved_git_dirs[dir]
endfunction
let s:commondirs = {}
function! FugitiveCommonDir(...) abort
let dir = call('FugitiveActualDir', a:000)
if empty(dir)
return ''
endif
if has_key(s:commondirs, dir)
return s:commondirs[dir]
endif
if getfsize(dir . '/HEAD') >= 10
let cdir = get(s:ReadFile(dir . '/commondir', 1), 0, '')
if cdir =~# '^/\|^\a:/'
let s:commondirs[dir] = s:Slash(FugitiveVimPath(cdir))
elseif len(cdir)
let s:commondirs[dir] = simplify(dir . '/' . cdir)
else
let s:commondirs[dir] = dir
endif
else
let s:commondirs[dir] = dir
endif
return s:commondirs[dir]
endfunction
function! FugitiveWorkTree(...) abort
let tree = s:Tree(FugitiveGitDir(a:0 ? a:1 : -1))
if tree isnot# 0 || a:0 > 1
return tree
else
return ''
endif
endfunction
function! FugitiveIsGitDir(...) abort
if !a:0 || type(a:1) !=# type('')
return !empty(call('FugitiveGitDir', a:000))
endif
let path = substitute(a:1, '[\/]$', '', '') . '/'
return len(path) && getfsize(path.'HEAD') > 10 && (
\ isdirectory(path.'objects') && isdirectory(path.'refs') ||
\ getftype(path.'commondir') ==# 'file')
endfunction
function! s:ReadFile(path, line_count) abort
if v:version < 800 && !filereadable(a:path)
return []
endif
try
return readfile(a:path, 'b', a:line_count)
catch
return []
endtry
endfunction
let s:worktree_for_dir = {}
let s:dir_for_worktree = {}
function! s:Tree(path) abort
if a:path =~# '/\.git$'
return len(a:path) ==# 5 ? '/' : a:path[0:-6]
elseif a:path ==# ''
return ''
endif
let dir = FugitiveActualDir(a:path)
if !has_key(s:worktree_for_dir, dir)
let s:worktree_for_dir[dir] = ''
let ext_wtc_pat = 'v:val =~# "^\\s*worktreeConfig *= *\\%(true\\|yes\\|on\\|1\\) *$"'
let config = s:ReadFile(dir . '/config', 50)
if len(config)
let ext_wtc_config = filter(copy(config), ext_wtc_pat)
if len(ext_wtc_config) == 1 && filereadable(dir . '/config.worktree')
let config += s:ReadFile(dir . '/config.worktree', 50)
endif
else
let worktree = fnamemodify(FugitiveVimPath(get(s:ReadFile(dir . '/gitdir', 1), '0', '')), ':h')
if worktree ==# '.'
unlet! worktree
endif
if len(filter(s:ReadFile(FugitiveCommonDir(dir) . '/config', 50), ext_wtc_pat))
let config = s:ReadFile(dir . '/config.worktree', 50)
endif
endif
if len(config)
let wt_config = filter(copy(config), 'v:val =~# "^\\s*worktree *="')
if len(wt_config)
let worktree = FugitiveVimPath(matchstr(wt_config[0], '= *\zs.*'))
elseif !exists('worktree')
call filter(config,'v:val =~# "^\\s*bare *= *true *$"')
if empty(config)
let s:worktree_for_dir[dir] = 0
endif
endif
endif
if exists('worktree')
let s:worktree_for_dir[dir] = s:Slash(resolve(worktree))
let s:dir_for_worktree[s:worktree_for_dir[dir]] = dir
endif
endif
if s:worktree_for_dir[dir] =~# '^\.'
return simplify(dir . '/' . s:worktree_for_dir[dir])
else
return s:worktree_for_dir[dir]
endif
endfunction
function! s:CeilingDirectories() abort
if !exists('s:ceiling_directories')
let s:ceiling_directories = []
let resolve = 1
for dir in split($GIT_CEILING_DIRECTORIES, has('win32') ? ';' : ':', 1)
if empty(dir)
let resolve = 0
elseif resolve
call add(s:ceiling_directories, s:Slash(resolve(dir)))
else
call add(s:ceiling_directories, s:Slash(dir))
endif
endfor
endif
return s:ceiling_directories + get(g:, 'ceiling_directories', [s:Slash(fnamemodify(expand('~'), ':h'))])
endfunction
function! s:ResolveGitDir(git_dir) abort
let type = getftype(a:git_dir)
if type ==# 'dir' && FugitiveIsGitDir(a:git_dir)
return a:git_dir
elseif type ==# 'link' && FugitiveIsGitDir(a:git_dir)
return resolve(a:git_dir)
elseif type !=# ''
let line = get(s:ReadFile(a:git_dir, 1), 0, '')
let file_dir = s:Slash(FugitiveVimPath(matchstr(line, '^gitdir: \zs.*')))
if file_dir !~# '^/\|^\a:\|^$' && a:git_dir =~# '/\.git$' && FugitiveIsGitDir(a:git_dir[0:-5] . file_dir)
return simplify(a:git_dir[0:-5] . file_dir)
elseif file_dir =~# '^/\|^\a:' && FugitiveIsGitDir(file_dir)
return file_dir
endif
endif
return ''
endfunction
function! FugitiveExtractGitDir(path) abort
if type(a:path) ==# type({})
return get(a:path, 'fugitive_dir', get(a:path, 'git_dir', ''))
elseif type(a:path) == type(0)
let path = s:Slash(a:path > 0 ? bufname(a:path) : bufname(''))
else
let path = s:Slash(a:path)
endif
if path =~# '^fugitive://'
return fugitive#Parse(path)[1]
elseif empty(path)
return ''
endif
let pre = substitute(matchstr(path, '^\a\a\+\ze:'), '^.', '\u&', '')
if len(pre) && exists('*' . pre . 'Real')
let path = {pre}Real(path)
endif
let root = s:Slash(fnamemodify(path, ':p:h'))
let previous = ""
let env_git_dir = len($GIT_DIR) ? s:Slash(simplify(fnamemodify(FugitiveVimPath($GIT_DIR), ':p:s?[\/]$??'))) : ''
call s:Tree(env_git_dir)
let ceiling_directories = s:CeilingDirectories()
while root !=# previous && root !~# '^$\|^//[^/]*$'
if index(ceiling_directories, root) >= 0
break
endif
if root ==# $GIT_WORK_TREE && FugitiveIsGitDir(env_git_dir)
return env_git_dir
elseif has_key(s:dir_for_worktree, root)
return s:dir_for_worktree[root]
endif
let dir = substitute(root, '[\/]$', '', '') . '/.git'
let resolved = s:ResolveGitDir(dir)
if !empty(resolved)
let s:resolved_git_dirs[dir] = resolved
return dir is# resolved || s:Tree(resolved) is# 0 ? dir : resolved
elseif FugitiveIsGitDir(root)
let s:resolved_git_dirs[root] = root
return root
endif
let previous = root
let root = fnamemodify(root, ':h')
endwhile
return ''
endfunction
function! FugitiveDetect(...) abort
if v:version < 704
return ''
endif
if exists('b:git_dir') && b:git_dir =~# '^$\|' . s:bad_git_dir
unlet b:git_dir
endif
if !exists('b:git_dir')
let b:git_dir = FugitiveExtractGitDir(a:0 ? a:1 : bufnr(''))
endif
return ''
endfunction
function! FugitiveGitPath(path) abort
return s:Slash(a:path)
endfunction
if exists('+shellslash')
function! s:Slash(path) abort
return tr(a:path, '\', '/')
endfunction
function! s:VimSlash(path) abort
return tr(a:path, '\/', &shellslash ? '//' : '\\')
endfunction
function FugitiveVimPath(path) abort
return tr(a:path, '\/', &shellslash ? '//' : '\\')
endfunction
else
function! s:Slash(path) abort
return a:path
endfunction
function! s:VimSlash(path) abort
return a:path
endfunction
if has('win32unix') && filereadable('/git-bash.exe')
function! FugitiveVimPath(path) abort
return substitute(a:path, '^\(\a\):', '/\l\1', '')
endfunction
else
function! FugitiveVimPath(path) abort
return a:path
endfunction
endif
endif
function! s:ProjectionistDetect() abort
let file = s:Slash(get(g:, 'projectionist_file', ''))
let dir = FugitiveExtractGitDir(file)
let base = matchstr(file, '^fugitive://.\{-\}//\x\+')
if empty(base)
let base = s:Tree(dir)
endif
if !empty(base)
if exists('+shellslash') && !&shellslash
let base = tr(base, '/', '\')
endif
let file = FugitiveFind('.git/info/projections.json', dir)
if filereadable(file)
call projectionist#append(base, file)
endif
endif
endfunction
let s:addr_other = has('patch-8.1.560') || has('nvim-0.5.0') ? '-addr=other' : ''
let s:addr_tabs = has('patch-7.4.542') ? '-addr=tabs' : ''
let s:addr_wins = has('patch-7.4.542') ? '-addr=windows' : ''
if exists(':G') != 2
command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#Complete G exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)
endif
command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#Complete Git exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)
if exists(':Gstatus') != 2 && get(g:, 'fugitive_legacy_commands', 0)
exe 'command! -bang -bar -range=-1' s:addr_other 'Gstatus exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Gstatus is deprecated in favor of :Git (with no arguments)"|echohl NONE'
endif
for s:cmd in ['Commit', 'Revert', 'Merge', 'Rebase', 'Pull', 'Push', 'Fetch', 'Blame']
if exists(':G' . tolower(s:cmd)) != 2 && get(g:, 'fugitive_legacy_commands', 0)
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#' . s:cmd . 'Complete G' . tolower(s:cmd)
\ 'echohl WarningMSG|echomsg ":G' . tolower(s:cmd) . ' is deprecated in favor of :Git ' . tolower(s:cmd) . '"|echohl NONE|'
\ 'exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", "' . tolower(s:cmd) . ' " . <q-args>)'
endif
endfor
unlet s:cmd
exe "command! -bar -bang -nargs=? -complete=customlist,fugitive#CdComplete Gcd exe fugitive#Cd(<q-args>, 0)"
exe "command! -bar -bang -nargs=? -complete=customlist,fugitive#CdComplete Glcd exe fugitive#Cd(<q-args>, 1)"
exe 'command! -bang -nargs=? -range=-1' s:addr_wins '-complete=customlist,fugitive#GrepComplete Ggrep exe fugitive#GrepCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bang -nargs=? -range=-1' s:addr_wins '-complete=customlist,fugitive#GrepComplete Glgrep exe fugitive#GrepCommand(0, <count> > 0 ? <count> : 0, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Gclog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "c")'
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete GcLog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "c")'
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Gllog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "l")'
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete GlLog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "l")'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Ge exe fugitive#Open("edit<bang>", 0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gedit exe fugitive#Open("edit<bang>", 0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gpedit exe fugitive#Open("pedit", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_other '-complete=customlist,fugitive#EditComplete Gsplit exe fugitive#Open((<count> > 0 ? <count> : "").(<count> ? "split" : "edit"), <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_other '-complete=customlist,fugitive#EditComplete Gvsplit exe fugitive#Open((<count> > 0 ? <count> : "").(<count> ? "vsplit" : "edit!"), <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_tabs '-complete=customlist,fugitive#EditComplete Gtabedit exe fugitive#Open((<count> >= 0 ? <count> : "")."tabedit", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gdrop exe fugitive#DropCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
if exists(':Gr') != 2
exe 'command! -bar -bang -nargs=* -range=-1 -complete=customlist,fugitive#ReadComplete Gr exe fugitive#ReadCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
endif
exe 'command! -bar -bang -nargs=* -range=-1 -complete=customlist,fugitive#ReadComplete Gread exe fugitive#ReadCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gdiffsplit exe fugitive#Diffsplit(1, <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Ghdiffsplit exe fugitive#Diffsplit(0, <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gvdiffsplit exe fugitive#Diffsplit(0, <bang>0, "vertical <mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gw exe fugitive#WriteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwrite exe fugitive#WriteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwq exe fugitive#WqCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=0 GRemove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=0 GUnlink exe fugitive#UnlinkCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=0 GDelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject GMove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete GRename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
if exists(':Gremove') != 2 && get(g:, 'fugitive_legacy_commands', 0)
exe 'command! -bar -bang -nargs=0 Gremove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Gremove is deprecated in favor of :GRemove"|echohl NONE'
elseif exists(':Gremove') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bar -bang -nargs=0 Gremove echoerr ":Gremove has been removed in favor of :GRemove"'
endif
if exists(':Gdelete') != 2 && get(g:, 'fugitive_legacy_commands', 0)
exe 'command! -bar -bang -nargs=0 Gdelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Gdelete is deprecated in favor of :GDelete"|echohl NONE'
elseif exists(':Gdelete') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bar -bang -nargs=0 Gdelete echoerr ":Gremove has been removed in favor of :GRemove"'
endif
if exists(':Gmove') != 2 && get(g:, 'fugitive_legacy_commands', 0)
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject Gmove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Gmove is deprecated in favor of :GMove"|echohl NONE'
elseif exists(':Gmove') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bar -bang -nargs=? -complete=customlist,fugitive#CompleteObject Gmove'
\ 'echoerr ":Gmove has been removed in favor of :GMove"'
endif
if exists(':Grename') != 2 && get(g:, 'fugitive_legacy_commands', 0)
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete Grename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Grename is deprecated in favor of :GRename"|echohl NONE'
elseif exists(':Grename') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bar -bang -nargs=? -complete=customlist,fugitive#RenameComplete Grename'
\ 'echoerr ":Grename has been removed in favor of :GRename"'
endif
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject GBrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
if exists(':Gbrowse') != 2 && get(g:, 'fugitive_legacy_commands', 0)
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|if <bang>1|redraw!|endif|echohl WarningMSG|echomsg ":Gbrowse is deprecated in favor of :GBrowse"|echohl NONE'
elseif exists(':Gbrowse') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse'
\ 'echoerr ":Gbrowse has been removed in favor of :GBrowse"'
endif
if v:version < 704
finish
endif
let g:io_fugitive = {
\ 'simplify': function('fugitive#simplify'),
\ 'resolve': function('fugitive#resolve'),
\ 'getftime': function('fugitive#getftime'),
\ 'getfsize': function('fugitive#getfsize'),
\ 'getftype': function('fugitive#getftype'),
\ 'filereadable': function('fugitive#filereadable'),
\ 'filewritable': function('fugitive#filewritable'),
\ 'isdirectory': function('fugitive#isdirectory'),
\ 'getfperm': function('fugitive#getfperm'),
\ 'setfperm': function('fugitive#setfperm'),
\ 'readfile': function('fugitive#readfile'),
\ 'writefile': function('fugitive#writefile'),
\ 'glob': function('fugitive#glob'),
\ 'delete': function('fugitive#delete'),
\ 'Real': function('FugitiveReal')}
augroup fugitive
autocmd!
autocmd BufNewFile,BufReadPost *
\ if exists('b:git_dir') && b:git_dir =~# '^$\|' . s:bad_git_dir |
\ unlet b:git_dir |
\ endif
autocmd FileType netrw
\ if exists('b:git_dir') && b:git_dir =~# '^$\|' . s:bad_git_dir |
\ unlet b:git_dir |
\ endif
autocmd BufFilePost * unlet! b:git_dir
autocmd FileType git
\ call fugitive#MapCfile()
autocmd FileType gitcommit
\ call fugitive#MapCfile('fugitive#MessageCfile()')
autocmd FileType git,gitcommit
\ if &foldtext ==# 'foldtext()' |
\ setlocal foldtext=fugitive#Foldtext() |
\ endif
autocmd FileType fugitive
\ call fugitive#MapCfile('fugitive#PorcelainCfile()')
autocmd FileType gitrebase
\ let &l:include = '^\%(pick\|squash\|edit\|reword\|fixup\|drop\|[pserfd]\)\>' |
\ if &l:includeexpr !~# 'Fugitive' |
\ let &l:includeexpr = 'v:fname =~# ''^\x\{4,\}$'' && len(FugitiveGitDir()) ? FugitiveFind(v:fname) : ' .
\ (len(&l:includeexpr) ? &l:includeexpr : 'v:fname') |
\ endif |
\ let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'exe') . '|setl inex= inc='
autocmd BufReadCmd index{,.lock} nested
\ if FugitiveIsGitDir(expand('<amatch>:p:h')) |
\ let b:git_dir = s:Slash(expand('<amatch>:p:h')) |
\ exe fugitive#BufReadStatus(v:cmdbang) |
\ elseif filereadable(expand('<amatch>')) |
\ silent doautocmd BufReadPre |
\ keepalt noautocmd read <amatch> |
\ silent 1delete_ |
\ silent doautocmd BufReadPost |
\ else |
\ silent doautocmd BufNewFile |
\ endif
autocmd BufReadCmd fugitive://* nested exe fugitive#BufReadCmd() |
\ if &path =~# '^\.\%(,\|$\)' |
\ let &l:path = substitute(&path, '^\.,\=', '', '') |
\ endif
autocmd BufWriteCmd fugitive://* nested exe fugitive#BufWriteCmd()
autocmd FileReadCmd fugitive://* nested exe fugitive#FileReadCmd()
autocmd FileWriteCmd fugitive://* nested exe fugitive#FileWriteCmd()
if exists('##SourceCmd')
autocmd SourceCmd fugitive://* nested exe fugitive#SourceCmd()
endif
autocmd User Flags call Hoist('buffer', function('FugitiveStatusline'))
autocmd User ProjectionistDetect call s:ProjectionistDetect()
augroup END
nmap <script><silent> <Plug>fugitive:y<C-G> :<C-U>call setreg(v:register, fugitive#Object(@%))<CR>
nmap <script> <Plug>fugitive: <Nop>
if get(g:, 'fugitive_no_maps')
finish
endif
function! s:Map(mode, lhs, rhs, flags) abort
let flags = a:flags . (a:rhs =~# '<Plug>' ? '' : '<script>') . '<nowait>'
let head = a:lhs
let tail = ''
let keys = get(g:, a:mode.'remap', {})
if len(keys) && type(keys) == type({})
while !empty(head)
if has_key(keys, head)
let head = keys[head]
if empty(head)
return
endif
break
endif
let tail = matchstr(head, '<[^<>]*>$\|.$') . tail
let head = substitute(head, '<[^<>]*>$\|.$', '', '')
endwhile
endif
if empty(mapcheck(head.tail, a:mode))
exe a:mode.'map' flags head.tail a:rhs
endif
endfunction
call s:Map('c', '<C-R><C-G>', 'fnameescape(fugitive#Object(@%))', '<expr>')
call s:Map('n', 'y<C-G>', ':<C-U>call setreg(v:register, fugitive#Object(@%))<CR>', '<silent>')

57
bundle/vim-fugitive/syntax/fugitive.vim vendored Normal file
View File

@ -0,0 +1,57 @@
if exists("b:current_syntax")
finish
endif
syn sync fromstart
syn spell notoplevel
syn include @fugitiveDiff syntax/diff.vim
syn match fugitiveHeader /^[A-Z][a-z][^:]*:/
syn match fugitiveHeader /^Head:/ nextgroup=fugitiveHash,fugitiveSymbolicRef skipwhite
syn match fugitiveHeader /^Pull:\|^Rebase:\|^Merge:\|^Push:/ nextgroup=fugitiveSymbolicRef skipwhite
syn match fugitiveHelpHeader /^Help:/ nextgroup=fugitiveHelpTag skipwhite
syn match fugitiveHelpTag /\S\+/ contained
syn region fugitiveSection start=/^\%(.*(\d\++\=)$\)\@=/ contains=fugitiveHeading end=/^$/
syn cluster fugitiveSection contains=fugitiveSection
syn match fugitiveHeading /^[A-Z][a-z][^:]*\ze (\d\++\=)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite
syn match fugitiveCount /(\d\++\=)/hs=s+1,he=e-1 contained
syn match fugitivePreposition /\<\%([io]nto\|from\|to\|Rebasing\%( detached\)\=\)\>/ transparent contained nextgroup=fugitiveHash,fugitiveSymbolicRef skipwhite
syn match fugitiveInstruction /^\l\l\+\>/ contained containedin=@fugitiveSection nextgroup=fugitiveHash skipwhite
syn match fugitiveDone /^done\>/ contained containedin=@fugitiveSection nextgroup=fugitiveHash skipwhite
syn match fugitiveStop /^stop\>/ contained containedin=@fugitiveSection nextgroup=fugitiveHash skipwhite
syn match fugitiveModifier /^[MADRCU?]\{1,2} / contained containedin=@fugitiveSection
syn match fugitiveSymbolicRef /\.\@!\%(\.\.\@!\|[^[:space:][:cntrl:]\:.]\)\+\.\@<!/ contained
syn match fugitiveHash /^\x\{4,\}\S\@!/ contained containedin=@fugitiveSection
syn match fugitiveHash /\S\@<!\x\{4,\}\S\@!/ contained
syn region fugitiveHunk start=/^\%(@@\+ -\)\@=/ end=/^\%([A-Za-z?@]\|$\)\@=/ contains=diffLine,diffRemoved,diffAdded,diffNoEOL containedin=@fugitiveSection fold
for s:section in ['Untracked', 'Unstaged', 'Staged']
exe 'syn region fugitive' . s:section . 'Section start=/^\%(' . s:section . ' .*(\d\++\=)$\)\@=/ contains=fugitive' . s:section . 'Heading end=/^$/'
exe 'syn match fugitive' . s:section . 'Modifier /^[MADRCU?] / contained containedin=fugitive' . s:section . 'Section'
exe 'syn cluster fugitiveSection add=fugitive' . s:section . 'Section'
exe 'syn match fugitive' . s:section . 'Heading /^[A-Z][a-z][^:]*\ze (\d\++\=)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite'
endfor
unlet s:section
hi def link fugitiveHelpHeader fugitiveHeader
hi def link fugitiveHeader Label
hi def link fugitiveHelpTag Tag
hi def link fugitiveHeading PreProc
hi def link fugitiveUntrackedHeading PreCondit
hi def link fugitiveUnstagedHeading Macro
hi def link fugitiveStagedHeading Include
hi def link fugitiveModifier Type
hi def link fugitiveUntrackedModifier StorageClass
hi def link fugitiveUnstagedModifier Structure
hi def link fugitiveStagedModifier Typedef
hi def link fugitiveInstruction Type
hi def link fugitiveStop Function
hi def link fugitiveHash Identifier
hi def link fugitiveSymbolicRef Function
hi def link fugitiveCount Number
let b:current_syntax = "fugitive"

View File

@ -0,0 +1,7 @@
if exists("b:current_syntax") || !exists("*FugitiveGitDir")
finish
endif
call fugitive#BlameSyntax()
let b:current_syntax = "fugitiveblame"