utils 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +68 -0
- data/VERSION +1 -0
- data/bin/chroot-exec +12 -0
- data/bin/chroot-libs +18 -0
- data/bin/classify +37 -0
- data/bin/discover +137 -0
- data/bin/edit +74 -0
- data/bin/errf +32 -0
- data/bin/git-empty +8 -0
- data/bin/myex +90 -0
- data/bin/number_files +26 -0
- data/bin/same_files +37 -0
- data/bin/search +205 -0
- data/bin/sedit +3 -0
- data/bin/sshscreen +68 -0
- data/bin/term +21 -0
- data/bin/unquarantine_apps +8 -0
- data/bin/untest +17 -0
- data/bin/utils-install-config +10 -0
- data/bin/vacuum_firefox_sqlite +22 -0
- data/bin/xmp +74 -0
- data/lib/utils.rb +8 -0
- data/lib/utils/config.rb +23 -0
- data/lib/utils/config/gdb/asm +179 -0
- data/lib/utils/config/gdb/ruby +528 -0
- data/lib/utils/config/gdbinit +8 -0
- data/lib/utils/config/irbrc +455 -0
- data/lib/utils/config/rdebugrc +2 -0
- data/lib/utils/config/screenrc +143 -0
- data/lib/utils/config/vim/autoload/Align.vim +1029 -0
- data/lib/utils/config/vim/autoload/AlignMaps.vim +330 -0
- data/lib/utils/config/vim/autoload/rails.vim +4744 -0
- data/lib/utils/config/vim/autoload/rubycomplete.vim +801 -0
- data/lib/utils/config/vim/autoload/sqlcomplete.vim +741 -0
- data/lib/utils/config/vim/autoload/vimball.vim +750 -0
- data/lib/utils/config/vim/colors/flori.vim +113 -0
- data/lib/utils/config/vim/compiler/eruby.vim +40 -0
- data/lib/utils/config/vim/compiler/ruby.vim +67 -0
- data/lib/utils/config/vim/compiler/rubyunit.vim +34 -0
- data/lib/utils/config/vim/ftdetect/ragel.vim +2 -0
- data/lib/utils/config/vim/ftdetect/ruby.vim +17 -0
- data/lib/utils/config/vim/ftplugin/eruby.vim +100 -0
- data/lib/utils/config/vim/ftplugin/ruby.vim +260 -0
- data/lib/utils/config/vim/ftplugin/xml.vim +941 -0
- data/lib/utils/config/vim/indent/IndentAnything_html.vim +35 -0
- data/lib/utils/config/vim/indent/eruby.vim +77 -0
- data/lib/utils/config/vim/indent/javascript.vim +116 -0
- data/lib/utils/config/vim/indent/ruby.vim +377 -0
- data/lib/utils/config/vim/plugin/AlignMapsPlugin.vim +242 -0
- data/lib/utils/config/vim/plugin/AlignPlugin.vim +41 -0
- data/lib/utils/config/vim/plugin/Decho.vim +592 -0
- data/lib/utils/config/vim/plugin/IndentAnything.vim +675 -0
- data/lib/utils/config/vim/plugin/bufexplorer.vim +1144 -0
- data/lib/utils/config/vim/plugin/cecutil.vim +482 -0
- data/lib/utils/config/vim/plugin/fugitive.vim +1703 -0
- data/lib/utils/config/vim/plugin/lusty-explorer.vim +1509 -0
- data/lib/utils/config/vim/plugin/rails.vim +340 -0
- data/lib/utils/config/vim/plugin/rubyextra.vim +193 -0
- data/lib/utils/config/vim/plugin/surround.vim +628 -0
- data/lib/utils/config/vim/plugin/taglist.vim +4546 -0
- data/lib/utils/config/vim/plugin/test/IndentAnything/test.js +131 -0
- data/lib/utils/config/vim/plugin/vimballPlugin.vim +40 -0
- data/lib/utils/config/vim/syntax/Decho.vim +101 -0
- data/lib/utils/config/vim/syntax/eruby.vim +73 -0
- data/lib/utils/config/vim/syntax/javascript.vim +246 -0
- data/lib/utils/config/vim/syntax/ragel.vim +165 -0
- data/lib/utils/config/vim/syntax/ruby.vim +367 -0
- data/lib/utils/config/vimrc +461 -0
- data/lib/utils/file.rb +49 -0
- data/lib/utils/find.rb +54 -0
- data/lib/utils/md5.rb +23 -0
- data/lib/utils/patterns.rb +34 -0
- data/lib/utils/version.rb +8 -0
- data/utils.gemspec +33 -0
- metadata +183 -0
@@ -0,0 +1,1703 @@
|
|
1
|
+
" fugitive.vim - A Git wrapper so awesome, it should be illegal
|
2
|
+
" Maintainer: Tim Pope <vimNOSPAM@tpope.org>
|
3
|
+
" Version: 1.1
|
4
|
+
" GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim
|
5
|
+
|
6
|
+
if exists('g:loaded_fugitive') || &cp
|
7
|
+
finish
|
8
|
+
endif
|
9
|
+
let g:loaded_fugitive = 1
|
10
|
+
|
11
|
+
if !exists('g:fugitive_git_executable')
|
12
|
+
let g:fugitive_git_executable = 'git'
|
13
|
+
endif
|
14
|
+
|
15
|
+
" Utility {{{1
|
16
|
+
|
17
|
+
function! s:function(name) abort
|
18
|
+
return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '<SNR>\d\+_'),''))
|
19
|
+
endfunction
|
20
|
+
|
21
|
+
function! s:sub(str,pat,rep) abort
|
22
|
+
return substitute(a:str,'\v\C'.a:pat,a:rep,'')
|
23
|
+
endfunction
|
24
|
+
|
25
|
+
function! s:gsub(str,pat,rep) abort
|
26
|
+
return substitute(a:str,'\v\C'.a:pat,a:rep,'g')
|
27
|
+
endfunction
|
28
|
+
|
29
|
+
function! s:shellesc(arg) abort
|
30
|
+
if a:arg =~ '^[A-Za-z0-9_/.-]\+$'
|
31
|
+
return a:arg
|
32
|
+
elseif &shell =~# 'cmd' && a:arg !~# '"'
|
33
|
+
return '"'.a:arg.'"'
|
34
|
+
else
|
35
|
+
return shellescape(a:arg)
|
36
|
+
endif
|
37
|
+
endfunction
|
38
|
+
|
39
|
+
function! s:fnameescape(file) abort
|
40
|
+
if exists('*fnameescape')
|
41
|
+
return fnameescape(a:file)
|
42
|
+
else
|
43
|
+
return escape(a:file," \t\n*?[{`$\\%#'\"|!<")
|
44
|
+
endif
|
45
|
+
endfunction
|
46
|
+
|
47
|
+
function! s:throw(string) abort
|
48
|
+
let v:errmsg = 'fugitive: '.a:string
|
49
|
+
throw v:errmsg
|
50
|
+
endfunction
|
51
|
+
|
52
|
+
function! s:warn(str)
|
53
|
+
echohl WarningMsg
|
54
|
+
echomsg a:str
|
55
|
+
echohl None
|
56
|
+
let v:warningmsg = a:str
|
57
|
+
endfunction
|
58
|
+
|
59
|
+
function! s:shellslash(path)
|
60
|
+
if exists('+shellslash') && !&shellslash
|
61
|
+
return s:gsub(a:path,'\\','/')
|
62
|
+
else
|
63
|
+
return a:path
|
64
|
+
endif
|
65
|
+
endfunction
|
66
|
+
|
67
|
+
function! s:add_methods(namespace, method_names) abort
|
68
|
+
for name in a:method_names
|
69
|
+
let s:{a:namespace}_prototype[name] = s:function('s:'.a:namespace.'_'.name)
|
70
|
+
endfor
|
71
|
+
endfunction
|
72
|
+
|
73
|
+
let s:commands = []
|
74
|
+
function! s:command(definition) abort
|
75
|
+
let s:commands += [a:definition]
|
76
|
+
endfunction
|
77
|
+
|
78
|
+
function! s:define_commands()
|
79
|
+
for command in s:commands
|
80
|
+
exe 'command! -buffer '.command
|
81
|
+
endfor
|
82
|
+
endfunction
|
83
|
+
|
84
|
+
function! s:compatibility_check()
|
85
|
+
if exists('b:git_dir') && exists('*GitBranchInfoCheckGitDir') && !exists('g:fugitive_did_compatibility_warning')
|
86
|
+
let g:fugitive_did_compatibility_warning = 1
|
87
|
+
call s:warn("See http://github.com/tpope/vim-fugitive/issues#issue/1 for why you should remove git-branch-info.vim")
|
88
|
+
endif
|
89
|
+
endfunction
|
90
|
+
|
91
|
+
augroup fugitive_utility
|
92
|
+
autocmd!
|
93
|
+
autocmd User Fugitive call s:define_commands()
|
94
|
+
autocmd VimEnter * call s:compatibility_check()
|
95
|
+
augroup END
|
96
|
+
|
97
|
+
let s:abstract_prototype = {}
|
98
|
+
|
99
|
+
" }}}1
|
100
|
+
" Initialization {{{1
|
101
|
+
|
102
|
+
function! s:ExtractGitDir(path) abort
|
103
|
+
let path = s:shellslash(a:path)
|
104
|
+
if path =~? '^fugitive://.*//'
|
105
|
+
return matchstr(path,'fugitive://\zs.\{-\}\ze//')
|
106
|
+
endif
|
107
|
+
let fn = fnamemodify(path,':s?[\/]$??')
|
108
|
+
let ofn = ""
|
109
|
+
let nfn = fn
|
110
|
+
while fn != ofn
|
111
|
+
if isdirectory(fn . '/.git')
|
112
|
+
return s:sub(simplify(fnamemodify(fn . '/.git',':p')),'\W$','')
|
113
|
+
elseif fn =~ '\.git$' && filereadable(fn . '/HEAD')
|
114
|
+
return s:sub(simplify(fnamemodify(fn,':p')),'\W$','')
|
115
|
+
endif
|
116
|
+
let ofn = fn
|
117
|
+
let fn = fnamemodify(ofn,':h')
|
118
|
+
endwhile
|
119
|
+
return ''
|
120
|
+
endfunction
|
121
|
+
|
122
|
+
function! s:Detect(path)
|
123
|
+
if exists('b:git_dir') && b:git_dir ==# ''
|
124
|
+
unlet b:git_dir
|
125
|
+
endif
|
126
|
+
if !exists('b:git_dir')
|
127
|
+
let dir = s:ExtractGitDir(a:path)
|
128
|
+
if dir != ''
|
129
|
+
let b:git_dir = dir
|
130
|
+
endif
|
131
|
+
endif
|
132
|
+
if exists('b:git_dir')
|
133
|
+
silent doautocmd User Fugitive
|
134
|
+
cnoremap <expr> <buffer> <C-R><C-G> fugitive#buffer().rev()
|
135
|
+
if expand('%:p') =~# '//'
|
136
|
+
let buffer = fugitive#buffer()
|
137
|
+
call buffer.setvar('&path',s:sub(buffer.getvar('&path'),'^\.%(,|$)',''))
|
138
|
+
endif
|
139
|
+
endif
|
140
|
+
endfunction
|
141
|
+
|
142
|
+
augroup fugitive
|
143
|
+
autocmd!
|
144
|
+
autocmd BufNewFile,BufReadPost * call s:Detect(expand('<amatch>:p'))
|
145
|
+
autocmd FileType netrw call s:Detect(expand('<amatch>:p'))
|
146
|
+
autocmd VimEnter * if expand('<amatch>')==''|call s:Detect(getcwd())|endif
|
147
|
+
autocmd BufWinLeave * execute getbufvar(+expand('<abuf>'), 'fugitive_restore')
|
148
|
+
augroup END
|
149
|
+
|
150
|
+
" }}}1
|
151
|
+
" Repository {{{1
|
152
|
+
|
153
|
+
let s:repo_prototype = {}
|
154
|
+
let s:repos = {}
|
155
|
+
|
156
|
+
function! s:repo(...) abort
|
157
|
+
let dir = a:0 ? a:1 : (exists('b:git_dir') && b:git_dir !=# '' ? b:git_dir : s:ExtractGitDir(expand('%:p')))
|
158
|
+
if dir !=# ''
|
159
|
+
if has_key(s:repos,dir)
|
160
|
+
let repo = get(s:repos,dir)
|
161
|
+
else
|
162
|
+
let repo = {'git_dir': dir}
|
163
|
+
let s:repos[dir] = repo
|
164
|
+
endif
|
165
|
+
return extend(extend(repo,s:repo_prototype,'keep'),s:abstract_prototype,'keep')
|
166
|
+
endif
|
167
|
+
call s:throw('not a git repository: '.expand('%:p'))
|
168
|
+
endfunction
|
169
|
+
|
170
|
+
function! s:repo_dir(...) dict abort
|
171
|
+
return join([self.git_dir]+a:000,'/')
|
172
|
+
endfunction
|
173
|
+
|
174
|
+
function! s:repo_tree(...) dict abort
|
175
|
+
if !self.bare()
|
176
|
+
let dir = fnamemodify(self.git_dir,':h')
|
177
|
+
return join([dir]+a:000,'/')
|
178
|
+
endif
|
179
|
+
call s:throw('no work tree')
|
180
|
+
endfunction
|
181
|
+
|
182
|
+
function! s:repo_bare() dict abort
|
183
|
+
return self.dir() !~# '/\.git$'
|
184
|
+
endfunction
|
185
|
+
|
186
|
+
function! s:repo_translate(spec) dict abort
|
187
|
+
if a:spec ==# '.' || a:spec ==# '/.'
|
188
|
+
return self.bare() ? self.dir() : self.tree()
|
189
|
+
elseif a:spec =~# '^/'
|
190
|
+
return fnamemodify(self.dir(),':h').a:spec
|
191
|
+
elseif a:spec =~# '^:[0-3]:'
|
192
|
+
return 'fugitive://'.self.dir().'//'.a:spec[1].'/'.a:spec[3:-1]
|
193
|
+
elseif a:spec ==# ':'
|
194
|
+
if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(s:repo().dir())] ==# s:repo().dir('') && filereadable($GIT_INDEX_FILE)
|
195
|
+
return fnamemodify($GIT_INDEX_FILE,':p')
|
196
|
+
else
|
197
|
+
return self.dir('index')
|
198
|
+
endif
|
199
|
+
elseif a:spec =~# '^:/'
|
200
|
+
let ref = self.rev_parse(matchstr(a:spec,'.[^:]*'))
|
201
|
+
return 'fugitive://'.self.dir().'//'.ref
|
202
|
+
elseif a:spec =~# '^:'
|
203
|
+
return 'fugitive://'.self.dir().'//0/'.a:spec[1:-1]
|
204
|
+
elseif a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(self.dir(a:spec))
|
205
|
+
return self.dir(a:spec)
|
206
|
+
elseif filereadable(s:repo().dir('refs/'.a:spec))
|
207
|
+
return self.dir('refs/'.a:spec)
|
208
|
+
elseif filereadable(s:repo().dir('refs/tags/'.a:spec))
|
209
|
+
return self.dir('refs/tags/'.a:spec)
|
210
|
+
elseif filereadable(s:repo().dir('refs/heads/'.a:spec))
|
211
|
+
return self.dir('refs/heads/'.a:spec)
|
212
|
+
elseif filereadable(s:repo().dir('refs/remotes/'.a:spec))
|
213
|
+
return self.dir('refs/remotes/'.a:spec)
|
214
|
+
elseif filereadable(s:repo().dir('refs/remotes/'.a:spec.'/HEAD'))
|
215
|
+
return self.dir('refs/remotes/'.a:spec,'/HEAD')
|
216
|
+
else
|
217
|
+
try
|
218
|
+
let ref = self.rev_parse(matchstr(a:spec,'[^:]*'))
|
219
|
+
let path = s:sub(matchstr(a:spec,':.*'),'^:','/')
|
220
|
+
return 'fugitive://'.self.dir().'//'.ref.path
|
221
|
+
catch /^fugitive:/
|
222
|
+
return self.tree(a:spec)
|
223
|
+
endtry
|
224
|
+
endif
|
225
|
+
endfunction
|
226
|
+
|
227
|
+
call s:add_methods('repo',['dir','tree','bare','translate'])
|
228
|
+
|
229
|
+
function! s:repo_git_command(...) dict abort
|
230
|
+
let git = g:fugitive_git_executable . ' --git-dir='.s:shellesc(self.git_dir)
|
231
|
+
return git.join(map(copy(a:000),'" ".s:shellesc(v:val)'),'')
|
232
|
+
endfunction
|
233
|
+
|
234
|
+
function! s:repo_git_chomp(...) dict abort
|
235
|
+
return s:sub(system(call(self.git_command,a:000,self)),'\n$','')
|
236
|
+
endfunction
|
237
|
+
|
238
|
+
function! s:repo_git_chomp_in_tree(...) dict abort
|
239
|
+
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
240
|
+
let dir = getcwd()
|
241
|
+
try
|
242
|
+
execute cd.'`=s:repo().tree()`'
|
243
|
+
return call(s:repo().git_chomp, a:000, s:repo())
|
244
|
+
finally
|
245
|
+
execute cd.'`=dir`'
|
246
|
+
endtry
|
247
|
+
endfunction
|
248
|
+
|
249
|
+
function! s:repo_rev_parse(rev) dict abort
|
250
|
+
let hash = self.git_chomp('rev-parse','--verify',a:rev)
|
251
|
+
if hash =~ '^\x\{40\}$'
|
252
|
+
return hash
|
253
|
+
endif
|
254
|
+
call s:throw('rev-parse '.a:rev.': '.hash)
|
255
|
+
endfunction
|
256
|
+
|
257
|
+
call s:add_methods('repo',['git_command','git_chomp','git_chomp_in_tree','rev_parse'])
|
258
|
+
|
259
|
+
function! s:repo_dirglob(base) dict abort
|
260
|
+
let base = s:sub(a:base,'^/','')
|
261
|
+
let matches = split(glob(self.tree(s:gsub(base,'/','*&').'*/')),"\n")
|
262
|
+
call map(matches,'v:val[ strlen(self.tree())+(a:base !~ "^/") : -1 ]')
|
263
|
+
return matches
|
264
|
+
endfunction
|
265
|
+
|
266
|
+
function! s:repo_superglob(base) dict abort
|
267
|
+
if a:base =~# '^/' || a:base !~# ':'
|
268
|
+
let results = []
|
269
|
+
if a:base !~# '^/'
|
270
|
+
let heads = ["HEAD","ORIG_HEAD","FETCH_HEAD","MERGE_HEAD"]
|
271
|
+
let heads += sort(split(s:repo().git_chomp("rev-parse","--symbolic","--branches","--tags","--remotes"),"\n"))
|
272
|
+
call filter(heads,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
|
273
|
+
let results += heads
|
274
|
+
endif
|
275
|
+
if !self.bare()
|
276
|
+
let base = s:sub(a:base,'^/','')
|
277
|
+
let matches = split(glob(self.tree(s:gsub(base,'/','*&').'*')),"\n")
|
278
|
+
call map(matches,'s:shellslash(v:val)')
|
279
|
+
call map(matches,'v:val !~ "/$" && isdirectory(v:val) ? v:val."/" : v:val')
|
280
|
+
call map(matches,'v:val[ strlen(self.tree())+(a:base !~ "^/") : -1 ]')
|
281
|
+
let results += matches
|
282
|
+
endif
|
283
|
+
return results
|
284
|
+
|
285
|
+
elseif a:base =~# '^:'
|
286
|
+
let entries = split(self.git_chomp('ls-files','--stage'),"\n")
|
287
|
+
call map(entries,'s:sub(v:val,".*(\\d)\\t(.*)",":\\1:\\2")')
|
288
|
+
if a:base !~# '^:[0-3]\%(:\|$\)'
|
289
|
+
call filter(entries,'v:val[1] == "0"')
|
290
|
+
call map(entries,'v:val[2:-1]')
|
291
|
+
endif
|
292
|
+
call filter(entries,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
|
293
|
+
return entries
|
294
|
+
|
295
|
+
else
|
296
|
+
let tree = matchstr(a:base,'.*[:/]')
|
297
|
+
let entries = split(self.git_chomp('ls-tree',tree),"\n")
|
298
|
+
call map(entries,'s:sub(v:val,"^04.*\\zs$","/")')
|
299
|
+
call map(entries,'tree.s:sub(v:val,".*\t","")')
|
300
|
+
return filter(entries,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
|
301
|
+
endif
|
302
|
+
endfunction
|
303
|
+
|
304
|
+
call s:add_methods('repo',['dirglob','superglob'])
|
305
|
+
|
306
|
+
function! s:repo_keywordprg() dict abort
|
307
|
+
let args = ' --git-dir='.escape(self.dir(),"\\\"' ").' show'
|
308
|
+
if has('gui_running') && !has('win32')
|
309
|
+
return g:fugitive_git_executable . ' --no-pager' . args
|
310
|
+
else
|
311
|
+
return g:fugitive_git_executable . args
|
312
|
+
endif
|
313
|
+
endfunction
|
314
|
+
|
315
|
+
call s:add_methods('repo',['keywordprg'])
|
316
|
+
|
317
|
+
" }}}1
|
318
|
+
" Buffer {{{1
|
319
|
+
|
320
|
+
let s:buffer_prototype = {}
|
321
|
+
|
322
|
+
function! s:buffer(...) abort
|
323
|
+
let buffer = {'#': bufnr(a:0 ? a:1 : '%')}
|
324
|
+
call extend(extend(buffer,s:buffer_prototype,'keep'),s:abstract_prototype,'keep')
|
325
|
+
if buffer.getvar('git_dir') !=# ''
|
326
|
+
return buffer
|
327
|
+
endif
|
328
|
+
call s:throw('not a git repository: '.expand('%:p'))
|
329
|
+
endfunction
|
330
|
+
|
331
|
+
function! fugitive#buffer(...) abort
|
332
|
+
return s:buffer(a:0 ? a:1 : '%')
|
333
|
+
endfunction
|
334
|
+
|
335
|
+
function! s:buffer_getvar(var) dict abort
|
336
|
+
return getbufvar(self['#'],a:var)
|
337
|
+
endfunction
|
338
|
+
|
339
|
+
function! s:buffer_setvar(var,value) dict abort
|
340
|
+
return setbufvar(self['#'],a:var,a:value)
|
341
|
+
endfunction
|
342
|
+
|
343
|
+
function! s:buffer_getline(lnum) dict abort
|
344
|
+
return getbufline(self['#'],a:lnum)[0]
|
345
|
+
endfunction
|
346
|
+
|
347
|
+
function! s:buffer_repo() dict abort
|
348
|
+
return s:repo(self.getvar('git_dir'))
|
349
|
+
endfunction
|
350
|
+
|
351
|
+
function! s:buffer_type(...) dict abort
|
352
|
+
if self.getvar('fugitive_type') != ''
|
353
|
+
let type = self.getvar('fugitive_type')
|
354
|
+
elseif fnamemodify(self.name(),':p') =~# '.\git/refs/\|\.git/\w*HEAD$'
|
355
|
+
let type = 'head'
|
356
|
+
elseif self.getline(1) =~ '^tree \x\{40\}$' && self.getline(2) == ''
|
357
|
+
let type = 'tree'
|
358
|
+
elseif self.getline(1) =~ '^\d\{6\} \w\{4\} \x\{40\}\>\t'
|
359
|
+
let type = 'tree'
|
360
|
+
elseif self.getline(1) =~ '^\d\{6\} \x\{40\}\> \d\t'
|
361
|
+
let type = 'index'
|
362
|
+
elseif isdirectory(self.name())
|
363
|
+
let type = 'directory'
|
364
|
+
elseif self.name() == ''
|
365
|
+
let type = 'null'
|
366
|
+
elseif filereadable(self.name())
|
367
|
+
let type = 'file'
|
368
|
+
else
|
369
|
+
let type = ''
|
370
|
+
endif
|
371
|
+
if a:0
|
372
|
+
return !empty(filter(copy(a:000),'v:val ==# type'))
|
373
|
+
else
|
374
|
+
return type
|
375
|
+
endif
|
376
|
+
endfunction
|
377
|
+
|
378
|
+
function! s:buffer_name() dict abort
|
379
|
+
let bufname = bufname(self['#'])
|
380
|
+
return s:shellslash(bufname == '' ? '' : fnamemodify(bufname,':p'))
|
381
|
+
endfunction
|
382
|
+
|
383
|
+
function! s:buffer_commit() dict abort
|
384
|
+
return matchstr(self.name(),'^fugitive://.\{-\}//\zs\w*')
|
385
|
+
endfunction
|
386
|
+
|
387
|
+
function! s:buffer_path(...) dict abort
|
388
|
+
let rev = matchstr(self.name(),'^fugitive://.\{-\}//\zs.*')
|
389
|
+
if rev != ''
|
390
|
+
let rev = s:sub(rev,'\w*','')
|
391
|
+
else
|
392
|
+
let rev = self.name()[strlen(self.repo().tree()) : -1]
|
393
|
+
endif
|
394
|
+
return s:sub(rev,'^/',a:0 ? a:1 : '')
|
395
|
+
endfunction
|
396
|
+
|
397
|
+
function! s:buffer_rev() dict abort
|
398
|
+
let rev = matchstr(self.name(),'^fugitive://.\{-\}//\zs.*')
|
399
|
+
if rev =~ '^\x/'
|
400
|
+
return ':'.rev[0].':'.rev[2:-1]
|
401
|
+
elseif rev =~ '.'
|
402
|
+
return s:sub(rev,'/',':')
|
403
|
+
elseif self.name() =~ '\.git/index$'
|
404
|
+
return ':'
|
405
|
+
elseif self.name() =~ '\.git/refs/\|\.git/.*HEAD$'
|
406
|
+
return self.name()[strlen(self.repo().dir())+1 : -1]
|
407
|
+
else
|
408
|
+
return self.path()
|
409
|
+
endif
|
410
|
+
endfunction
|
411
|
+
|
412
|
+
function! s:buffer_sha1() dict abort
|
413
|
+
if self.name() =~ '^fugitive://' || self.name() =~ '\.git/refs/\|\.git/.*HEAD$'
|
414
|
+
return self.repo().rev_parse(self.rev())
|
415
|
+
else
|
416
|
+
return ''
|
417
|
+
endif
|
418
|
+
endfunction
|
419
|
+
|
420
|
+
function! s:buffer_expand(rev) dict abort
|
421
|
+
if a:rev =~# '^:[0-3]$'
|
422
|
+
let file = a:rev.self.path(':')
|
423
|
+
elseif a:rev =~# '^-'
|
424
|
+
let file = 'HEAD^{}'.a:rev[1:-1].self.path(':')
|
425
|
+
elseif a:rev =~# '^@{'
|
426
|
+
let file = 'HEAD'.a:rev.self.path(':')
|
427
|
+
elseif a:rev =~# '^[~^]'
|
428
|
+
let commit = s:sub(self.commit(),'^\d=$','HEAD')
|
429
|
+
let file = commit.a:rev.self.path(':')
|
430
|
+
else
|
431
|
+
let file = a:rev
|
432
|
+
endif
|
433
|
+
return s:sub(file,'\%$',self.path())
|
434
|
+
endfunction
|
435
|
+
|
436
|
+
function! s:buffer_containing_commit() dict abort
|
437
|
+
if self.commit() =~# '^\d$'
|
438
|
+
return ':'
|
439
|
+
elseif self.commit() =~# '.'
|
440
|
+
return self.commit()
|
441
|
+
else
|
442
|
+
return 'HEAD'
|
443
|
+
endif
|
444
|
+
endfunction
|
445
|
+
|
446
|
+
call s:add_methods('buffer',['getvar','setvar','getline','repo','type','name','commit','path','rev','sha1','expand','containing_commit'])
|
447
|
+
|
448
|
+
" }}}1
|
449
|
+
" Git {{{1
|
450
|
+
|
451
|
+
call s:command("-bang -nargs=? -complete=customlist,s:GitComplete Git :execute s:Git(<bang>0,<q-args>)")
|
452
|
+
|
453
|
+
function! s:ExecuteInTree(cmd) abort
|
454
|
+
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
455
|
+
let dir = getcwd()
|
456
|
+
try
|
457
|
+
execute cd.'`=s:repo().tree()`'
|
458
|
+
execute a:cmd
|
459
|
+
finally
|
460
|
+
execute cd.'`=dir`'
|
461
|
+
endtry
|
462
|
+
endfunction
|
463
|
+
|
464
|
+
function! s:Git(bang,cmd) abort
|
465
|
+
let git = s:repo().git_command()
|
466
|
+
if has('gui_running') && !has('win32')
|
467
|
+
let git .= ' --no-pager'
|
468
|
+
endif
|
469
|
+
let cmd = matchstr(a:cmd,'\v\C.{-}%($|\\@<!%(\\\\)*\|)@=')
|
470
|
+
call s:ExecuteInTree('!'.git.' '.cmd)
|
471
|
+
call fugitive#reload_status()
|
472
|
+
return matchstr(a:cmd,'\v\C\\@<!%(\\\\)*\|\zs.*')
|
473
|
+
endfunction
|
474
|
+
|
475
|
+
function! s:GitComplete(A,L,P) abort
|
476
|
+
if !exists('s:exec_path')
|
477
|
+
let s:exec_path = s:sub(system(g:fugitive_git_executable.' --exec-path'),'\n$','')
|
478
|
+
endif
|
479
|
+
let cmds = map(split(glob(s:exec_path.'/git-*'),"\n"),'s:sub(v:val[strlen(s:exec_path)+5 : -1],"\\.exe$","")')
|
480
|
+
if a:L =~ ' [[:alnum:]-]\+ '
|
481
|
+
return s:repo().superglob(a:A)
|
482
|
+
elseif a:A == ''
|
483
|
+
return cmds
|
484
|
+
else
|
485
|
+
return filter(cmds,'v:val[0 : strlen(a:A)-1] ==# a:A')
|
486
|
+
endif
|
487
|
+
endfunction
|
488
|
+
|
489
|
+
" }}}1
|
490
|
+
" Gcd, Glcd {{{1
|
491
|
+
|
492
|
+
function! s:DirComplete(A,L,P) abort
|
493
|
+
let matches = s:repo().dirglob(a:A)
|
494
|
+
return matches
|
495
|
+
endfunction
|
496
|
+
|
497
|
+
call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Gcd :cd<bang> `=s:repo().bare() ? s:repo().dir(<q-args>) : s:repo().tree(<q-args>)`")
|
498
|
+
call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Glcd :lcd<bang> `=s:repo().bare() ? s:repo().dir(<q-args>) : s:repo().tree(<q-args>)`")
|
499
|
+
|
500
|
+
" }}}1
|
501
|
+
" Gstatus {{{1
|
502
|
+
|
503
|
+
call s:command("-bar Gstatus :execute s:Status()")
|
504
|
+
|
505
|
+
function! s:Status() abort
|
506
|
+
try
|
507
|
+
Gpedit :
|
508
|
+
wincmd P
|
509
|
+
nnoremap <buffer> <silent> q :<C-U>bdelete<CR>
|
510
|
+
catch /^fugitive:/
|
511
|
+
return 'echoerr v:errmsg'
|
512
|
+
endtry
|
513
|
+
return ''
|
514
|
+
endfunction
|
515
|
+
|
516
|
+
function! fugitive#reload_status() abort
|
517
|
+
let mytab = tabpagenr()
|
518
|
+
for tab in [mytab] + range(1,tabpagenr('$'))
|
519
|
+
for winnr in range(1,tabpagewinnr(tab,'$'))
|
520
|
+
if getbufvar(tabpagebuflist(tab)[winnr-1],'fugitive_type') ==# 'index'
|
521
|
+
execute 'tabnext '.tab
|
522
|
+
if winnr != winnr()
|
523
|
+
execute winnr.'wincmd w'
|
524
|
+
let restorewinnr = 1
|
525
|
+
endif
|
526
|
+
try
|
527
|
+
if !&modified
|
528
|
+
call s:BufReadIndex()
|
529
|
+
endif
|
530
|
+
finally
|
531
|
+
if exists('restorewinnr')
|
532
|
+
wincmd p
|
533
|
+
endif
|
534
|
+
execute 'tabnext '.mytab
|
535
|
+
endtry
|
536
|
+
endif
|
537
|
+
endfor
|
538
|
+
endfor
|
539
|
+
endfunction
|
540
|
+
|
541
|
+
function! s:StageDiff() abort
|
542
|
+
let section = getline(search('^# .*:$','bnW'))
|
543
|
+
let line = getline('.')
|
544
|
+
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
|
545
|
+
if filename ==# '' && section == '# Changes to be committed:'
|
546
|
+
return 'Git diff --cached'
|
547
|
+
elseif filename ==# ''
|
548
|
+
return 'Git diff'
|
549
|
+
elseif line =~# '^#\trenamed:' && filename =~ ' -> '
|
550
|
+
let [old, new] = split(filename,' -> ')
|
551
|
+
execute 'Gedit '.s:fnameescape(':0:'.new)
|
552
|
+
return 'Gdiff HEAD:'.s:fnameescape(old)
|
553
|
+
elseif section == '# Changes to be committed:'
|
554
|
+
execute 'Gedit '.s:fnameescape(':0:'.filename)
|
555
|
+
return 'Gdiff -'
|
556
|
+
else
|
557
|
+
execute 'Gedit '.s:fnameescape('/'.filename)
|
558
|
+
return 'Gdiff'
|
559
|
+
endif
|
560
|
+
endfunction
|
561
|
+
|
562
|
+
function! s:StageToggle(lnum1,lnum2) abort
|
563
|
+
try
|
564
|
+
let output = ''
|
565
|
+
for lnum in range(a:lnum1,a:lnum2)
|
566
|
+
let line = getline(lnum)
|
567
|
+
if getline('.') == '# Changes to be committed:'
|
568
|
+
return 'Gcommit'
|
569
|
+
endif
|
570
|
+
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
|
571
|
+
if filename ==# ''
|
572
|
+
continue
|
573
|
+
endif
|
574
|
+
if !exists('first_filename')
|
575
|
+
let first_filename = filename
|
576
|
+
endif
|
577
|
+
execute lnum
|
578
|
+
let section = getline(search('^# .*:$','bnW'))
|
579
|
+
if line =~# '^#\trenamed:' && filename =~ ' -> '
|
580
|
+
let cmd = ['mv','--'] + reverse(split(filename,' -> '))
|
581
|
+
let filename = cmd[-1]
|
582
|
+
elseif section =~? ' to be '
|
583
|
+
let cmd = ['reset','-q','--',filename]
|
584
|
+
elseif line =~# '^#\tdeleted:'
|
585
|
+
let cmd = ['rm','--',filename]
|
586
|
+
else
|
587
|
+
let cmd = ['add','--',filename]
|
588
|
+
endif
|
589
|
+
let output .= call(s:repo().git_chomp_in_tree,cmd,s:repo())."\n"
|
590
|
+
endfor
|
591
|
+
if exists('first_filename')
|
592
|
+
let jump = first_filename
|
593
|
+
let f = matchstr(getline(a:lnum1-1),'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
|
594
|
+
if f !=# '' | let jump = f | endif
|
595
|
+
let f = matchstr(getline(a:lnum2+1),'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
|
596
|
+
if f !=# '' | let jump = f | endif
|
597
|
+
silent! edit!
|
598
|
+
1
|
599
|
+
redraw
|
600
|
+
call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.jump.'\$','W')
|
601
|
+
endif
|
602
|
+
echo s:sub(s:gsub(output,'\n+','\n'),'\n$','')
|
603
|
+
catch /^fugitive:/
|
604
|
+
return 'echoerr v:errmsg'
|
605
|
+
endtry
|
606
|
+
return 'checktime'
|
607
|
+
endfunction
|
608
|
+
|
609
|
+
function! s:StagePatch(lnum1,lnum2) abort
|
610
|
+
let add = []
|
611
|
+
let reset = []
|
612
|
+
|
613
|
+
for lnum in range(a:lnum1,a:lnum2)
|
614
|
+
let line = getline(lnum)
|
615
|
+
if line == '# Changes to be committed:'
|
616
|
+
return 'Git reset --patch'
|
617
|
+
elseif line == '# Changed but not updated:'
|
618
|
+
return 'Git add --patch'
|
619
|
+
endif
|
620
|
+
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
|
621
|
+
if filename ==# ''
|
622
|
+
continue
|
623
|
+
endif
|
624
|
+
if !exists('first_filename')
|
625
|
+
let first_filename = filename
|
626
|
+
endif
|
627
|
+
execute lnum
|
628
|
+
let section = getline(search('^# .*:$','bnW'))
|
629
|
+
if line =~# '^#\trenamed:' && filename =~ ' -> '
|
630
|
+
let reset += [split(filename,' -> ')[1]]
|
631
|
+
elseif section =~? ' to be '
|
632
|
+
let reset += [filename]
|
633
|
+
elseif line !~# '^#\tdeleted:'
|
634
|
+
let add += [filename]
|
635
|
+
endif
|
636
|
+
endfor
|
637
|
+
try
|
638
|
+
if !empty(add)
|
639
|
+
execute "Git add --patch -- ".join(map(add,'s:shellesc(v:val)'))
|
640
|
+
endif
|
641
|
+
if !empty(reset)
|
642
|
+
execute "Git reset --patch -- ".join(map(add,'s:shellesc(v:val)'))
|
643
|
+
endif
|
644
|
+
if exists('first_filename')
|
645
|
+
silent! edit!
|
646
|
+
1
|
647
|
+
redraw
|
648
|
+
call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.first_filename.'\$','W')
|
649
|
+
endif
|
650
|
+
catch /^fugitive:/
|
651
|
+
return 'echoerr v:errmsg'
|
652
|
+
endtry
|
653
|
+
return 'checktime'
|
654
|
+
endfunction
|
655
|
+
|
656
|
+
" }}}1
|
657
|
+
" Gcommit {{{1
|
658
|
+
|
659
|
+
call s:command("-nargs=? -complete=customlist,s:CommitComplete Gcommit :execute s:Commit(<q-args>)")
|
660
|
+
|
661
|
+
function! s:Commit(args) abort
|
662
|
+
let old_type = s:buffer().type()
|
663
|
+
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
664
|
+
let dir = getcwd()
|
665
|
+
let msgfile = s:repo().dir('COMMIT_EDITMSG')
|
666
|
+
let outfile = tempname()
|
667
|
+
let errorfile = tempname()
|
668
|
+
try
|
669
|
+
execute cd.'`=s:repo().tree()`'
|
670
|
+
let command = ''
|
671
|
+
if &shell =~# 'cmd'
|
672
|
+
let old_editor = $GIT_EDITOR
|
673
|
+
let $GIT_EDITOR = 'false'
|
674
|
+
elseif &shell !~# 'csh'
|
675
|
+
let command = 'GIT_EDITOR=false '
|
676
|
+
endif
|
677
|
+
let command .= s:repo().git_command('commit').' '.a:args
|
678
|
+
if &shell =~# 'csh'
|
679
|
+
silent execute '!setenv GIT_EDITOR false; ('.command.' > '.outfile.') >& '.errorfile
|
680
|
+
elseif a:args =~# '\%(^\| \)--interactive\>'
|
681
|
+
execute '!'.command.' 2> '.errorfile
|
682
|
+
else
|
683
|
+
silent execute '!'.command.' > '.outfile.' 2> '.errorfile
|
684
|
+
endif
|
685
|
+
if !v:shell_error
|
686
|
+
if filereadable(outfile)
|
687
|
+
for line in readfile(outfile)
|
688
|
+
echo line
|
689
|
+
endfor
|
690
|
+
endif
|
691
|
+
return ''
|
692
|
+
else
|
693
|
+
let error = get(readfile(errorfile,'',1),0,'!')
|
694
|
+
if error =~# "'false'\\.$"
|
695
|
+
let args = a:args
|
696
|
+
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-[se]|--edit|--interactive)%($| )','')
|
697
|
+
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-F|--file|-m|--message)%(\s+|\=)%(''[^'']*''|"%(\\.|[^"])*"|\\.|\S)*','')
|
698
|
+
let args = s:gsub(args,'%(^| )@<=[%#]%(:\w)*','\=expand(submatch(0))')
|
699
|
+
let args = '-F '.s:shellesc(msgfile).' '.args
|
700
|
+
if args !~# '\%(^\| \)--cleanup\>'
|
701
|
+
let args = '--cleanup=strip '.args
|
702
|
+
endif
|
703
|
+
if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&mod
|
704
|
+
edit `=msgfile`
|
705
|
+
else
|
706
|
+
split `=msgfile`
|
707
|
+
endif
|
708
|
+
if old_type ==# 'index'
|
709
|
+
bdelete #
|
710
|
+
endif
|
711
|
+
let b:fugitive_commit_arguments = args
|
712
|
+
setlocal bufhidden=delete filetype=gitcommit
|
713
|
+
return '1'
|
714
|
+
elseif error ==# '!'
|
715
|
+
return s:Status()
|
716
|
+
else
|
717
|
+
call s:throw(error)
|
718
|
+
endif
|
719
|
+
endif
|
720
|
+
catch /^fugitive:/
|
721
|
+
return 'echoerr v:errmsg'
|
722
|
+
finally
|
723
|
+
if exists('old_editor')
|
724
|
+
let $GIT_EDITOR = old_editor
|
725
|
+
endif
|
726
|
+
call delete(outfile)
|
727
|
+
call delete(errorfile)
|
728
|
+
execute cd.'`=dir`'
|
729
|
+
call fugitive#reload_status()
|
730
|
+
endtry
|
731
|
+
endfunction
|
732
|
+
|
733
|
+
function! s:CommitComplete(A,L,P) abort
|
734
|
+
if a:A =~ '^-' || type(a:A) == type(0) " a:A is 0 on :Gcommit -<Tab>
|
735
|
+
let args = ['-C', '-F', '-a', '-c', '-e', '-i', '-m', '-n', '-o', '-q', '-s', '-t', '-u', '-v', '--all', '--allow-empty', '--amend', '--author=', '--cleanup=', '--dry-run', '--edit', '--file=', '--include', '--interactive', '--message=', '--no-verify', '--only', '--quiet', '--reedit-message=', '--reuse-message=', '--signoff', '--template=', '--untracked-files', '--verbose']
|
736
|
+
return filter(args,'v:val[0 : strlen(a:A)-1] ==# a:A')
|
737
|
+
else
|
738
|
+
return s:repo().superglob(a:A)
|
739
|
+
endif
|
740
|
+
endfunction
|
741
|
+
|
742
|
+
function! s:FinishCommit()
|
743
|
+
let args = getbufvar(+expand('<abuf>'),'fugitive_commit_arguments')
|
744
|
+
let g:args = args
|
745
|
+
if !empty(args)
|
746
|
+
call setbufvar(+expand('<abuf>'),'fugitive_commit_arguments','')
|
747
|
+
return s:Commit(args)
|
748
|
+
endif
|
749
|
+
return ''
|
750
|
+
endfunction
|
751
|
+
|
752
|
+
augroup fugitive_commit
|
753
|
+
autocmd!
|
754
|
+
autocmd VimLeavePre,BufDelete *.git/COMMIT_EDITMSG execute s:sub(s:FinishCommit(), '^echoerr (.*)', 'echohl ErrorMsg|echo \1|echohl NONE')
|
755
|
+
augroup END
|
756
|
+
|
757
|
+
" }}}1
|
758
|
+
" Ggrep, Glog {{{1
|
759
|
+
|
760
|
+
if !exists('g:fugitive_summary_format')
|
761
|
+
let g:fugitive_summary_format = '%s'
|
762
|
+
endif
|
763
|
+
|
764
|
+
call s:command("-bang -nargs=? -complete=customlist,s:EditComplete Ggrep :execute s:Grep(<bang>0,<q-args>)")
|
765
|
+
call s:command("-bar -bang -nargs=* -complete=customlist,s:EditComplete Glog :execute s:Log('grep<bang>',<f-args>)")
|
766
|
+
|
767
|
+
function! s:Grep(bang,arg) abort
|
768
|
+
let grepprg = &grepprg
|
769
|
+
let grepformat = &grepformat
|
770
|
+
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
771
|
+
let dir = getcwd()
|
772
|
+
try
|
773
|
+
execute cd.'`=s:repo().tree()`'
|
774
|
+
let &grepprg = s:repo().git_command('--no-pager', 'grep', '-n')
|
775
|
+
let &grepformat = '%f:%l:%m'
|
776
|
+
exe 'grep! '.escape(matchstr(a:arg,'\v\C.{-}%($|[''" ]\@=\|)@='),'|')
|
777
|
+
let list = getqflist()
|
778
|
+
for entry in list
|
779
|
+
if bufname(entry.bufnr) =~ ':'
|
780
|
+
let entry.filename = s:repo().translate(bufname(entry.bufnr))
|
781
|
+
unlet! entry.bufnr
|
782
|
+
elseif a:arg =~# '\%(^\| \)--cached\>'
|
783
|
+
let entry.filename = s:repo().translate(':0:'.bufname(entry.bufnr))
|
784
|
+
unlet! entry.bufnr
|
785
|
+
endif
|
786
|
+
endfor
|
787
|
+
call setqflist(list,'r')
|
788
|
+
if !a:bang && !empty(list)
|
789
|
+
return 'cfirst'.matchstr(a:arg,'\v\C[''" ]\zs\|.*')
|
790
|
+
else
|
791
|
+
return matchstr(a:arg,'\v\C[''" ]\|\zs.*')
|
792
|
+
endif
|
793
|
+
finally
|
794
|
+
let &grepprg = grepprg
|
795
|
+
let &grepformat = grepformat
|
796
|
+
execute cd.'`=dir`'
|
797
|
+
endtry
|
798
|
+
endfunction
|
799
|
+
|
800
|
+
function! s:Log(cmd,...)
|
801
|
+
let path = s:buffer().path('/')
|
802
|
+
if path =~# '^/\.git\%(/\|$\)' || index(a:000,'--') != -1
|
803
|
+
let path = ''
|
804
|
+
endif
|
805
|
+
let cmd = ['--no-pager', 'log', '--no-color']
|
806
|
+
let cmd += [escape('--pretty=format:fugitive://'.s:repo().dir().'//%H'.path.'::'.g:fugitive_summary_format,'%')]
|
807
|
+
if empty(filter(a:000[0 : index(a:000,'--')],'v:val !~# "^-"'))
|
808
|
+
if s:buffer().commit() =~# '\x\{40\}'
|
809
|
+
let cmd += [s:buffer().commit()]
|
810
|
+
elseif s:buffer().path() =~# '^\.git/refs/\|^\.git/.*HEAD$'
|
811
|
+
let cmd += [s:buffer().path()[5:-1]]
|
812
|
+
endif
|
813
|
+
end
|
814
|
+
let cmd += map(copy(a:000),'s:sub(v:val,"^\\%(%(:\\w)*)","\\=fnamemodify(s:buffer().path(),submatch(1))")')
|
815
|
+
if path =~# '/.'
|
816
|
+
let cmd += ['--',path[1:-1]]
|
817
|
+
endif
|
818
|
+
let grepformat = &grepformat
|
819
|
+
let grepprg = &grepprg
|
820
|
+
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
821
|
+
let dir = getcwd()
|
822
|
+
try
|
823
|
+
execute cd.'`=s:repo().tree()`'
|
824
|
+
let &grepprg = call(s:repo().git_command,cmd,s:repo())
|
825
|
+
let &grepformat = '%f::%m'
|
826
|
+
exe a:cmd
|
827
|
+
finally
|
828
|
+
let &grepformat = grepformat
|
829
|
+
let &grepprg = grepprg
|
830
|
+
execute cd.'`=dir`'
|
831
|
+
endtry
|
832
|
+
endfunction
|
833
|
+
|
834
|
+
" }}}1
|
835
|
+
" Gedit, Gpedit, Gsplit, Gvsplit, Gtabedit, Gread {{{1
|
836
|
+
|
837
|
+
function! s:Edit(cmd,...) abort
|
838
|
+
if a:0 && a:1 == ''
|
839
|
+
return ''
|
840
|
+
elseif a:0
|
841
|
+
let file = s:buffer().expand(a:1)
|
842
|
+
elseif s:buffer().commit() ==# '' && s:buffer().path('/') !~# '^/.git\>'
|
843
|
+
let file = s:buffer().path(':')
|
844
|
+
else
|
845
|
+
let file = s:buffer().path('/')
|
846
|
+
endif
|
847
|
+
try
|
848
|
+
let file = s:repo().translate(file)
|
849
|
+
catch /^fugitive:/
|
850
|
+
return 'echoerr v:errmsg'
|
851
|
+
endtry
|
852
|
+
if a:cmd =~# 'read!$' || a:cmd ==# 'read'
|
853
|
+
if a:cmd =~# '!$'
|
854
|
+
call s:warn(':Gread! is deprecated. Use :Gread')
|
855
|
+
endif
|
856
|
+
return 'silent %delete|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.')
|
857
|
+
else
|
858
|
+
if &previewwindow && getbufvar('','fugitive_type') ==# 'index'
|
859
|
+
wincmd p
|
860
|
+
endif
|
861
|
+
return a:cmd.' '.s:fnameescape(file)
|
862
|
+
endif
|
863
|
+
endfunction
|
864
|
+
|
865
|
+
function! s:EditComplete(A,L,P) abort
|
866
|
+
return s:repo().superglob(a:A)
|
867
|
+
endfunction
|
868
|
+
|
869
|
+
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Ge :execute s:Edit('edit<bang>',<f-args>)")
|
870
|
+
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gedit :execute s:Edit('edit<bang>',<f-args>)")
|
871
|
+
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gpedit :execute s:Edit('pedit<bang>',<f-args>)")
|
872
|
+
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gsplit :execute s:Edit('split<bang>',<f-args>)")
|
873
|
+
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gvsplit :execute s:Edit('vsplit<bang>',<f-args>)")
|
874
|
+
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gtabedit :execute s:Edit('tabedit<bang>',<f-args>)")
|
875
|
+
call s:command("-bar -bang -nargs=? -count -complete=customlist,s:EditComplete Gread :execute s:Edit((!<count> && <line1> ? '' : <count>).'read<bang>',<f-args>)")
|
876
|
+
|
877
|
+
" }}}1
|
878
|
+
" Gwrite {{{1
|
879
|
+
|
880
|
+
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gwrite :execute s:Write(<bang>0,<f-args>)")
|
881
|
+
|
882
|
+
function! s:Write(force,...) abort
|
883
|
+
if exists('b:fugitive_commit_arguments')
|
884
|
+
return 'write|bdelete'
|
885
|
+
elseif expand('%:t') == 'COMMIT_EDITMSG' && $GIT_INDEX_FILE != ''
|
886
|
+
return 'wq'
|
887
|
+
elseif s:buffer().type() == 'index'
|
888
|
+
return 'Gcommit'
|
889
|
+
endif
|
890
|
+
let mytab = tabpagenr()
|
891
|
+
let mybufnr = bufnr('')
|
892
|
+
let path = a:0 ? a:1 : s:buffer().path()
|
893
|
+
if path =~# '^:\d\>'
|
894
|
+
return 'write'.(a:force ? '! ' : ' ').s:fnameescape(s:repo().translate(s:buffer().expand(path)))
|
895
|
+
endif
|
896
|
+
let always_permitted = (s:buffer().path() ==# path && s:buffer().commit() =~# '^0\=$')
|
897
|
+
if !always_permitted && !a:force && s:repo().git_chomp_in_tree('diff','--name-status','HEAD','--',path) . s:repo().git_chomp_in_tree('ls-files','--others','--',path) !=# ''
|
898
|
+
let v:errmsg = 'fugitive: file has uncommitted changes (use ! to override)'
|
899
|
+
return 'echoerr v:errmsg'
|
900
|
+
endif
|
901
|
+
let file = s:repo().translate(path)
|
902
|
+
let treebufnr = 0
|
903
|
+
for nr in range(1,bufnr('$'))
|
904
|
+
if fnamemodify(bufname(nr),':p') ==# file
|
905
|
+
let treebufnr = nr
|
906
|
+
endif
|
907
|
+
endfor
|
908
|
+
|
909
|
+
if treebufnr > 0 && treebufnr != bufnr('')
|
910
|
+
let temp = tempname()
|
911
|
+
silent execute '%write '.temp
|
912
|
+
for tab in [mytab] + range(1,tabpagenr('$'))
|
913
|
+
for winnr in range(1,tabpagewinnr(tab,'$'))
|
914
|
+
if tabpagebuflist(tab)[winnr-1] == treebufnr
|
915
|
+
execute 'tabnext '.tab
|
916
|
+
if winnr != winnr()
|
917
|
+
execute winnr.'wincmd w'
|
918
|
+
let restorewinnr = 1
|
919
|
+
endif
|
920
|
+
try
|
921
|
+
let lnum = line('.')
|
922
|
+
let last = line('$')
|
923
|
+
silent execute '$read '.temp
|
924
|
+
silent execute '1,'.last.'delete_'
|
925
|
+
silent write!
|
926
|
+
silent execute lnum
|
927
|
+
let did = 1
|
928
|
+
finally
|
929
|
+
if exists('restorewinnr')
|
930
|
+
wincmd p
|
931
|
+
endif
|
932
|
+
execute 'tabnext '.mytab
|
933
|
+
endtry
|
934
|
+
endif
|
935
|
+
endfor
|
936
|
+
endfor
|
937
|
+
if !exists('did')
|
938
|
+
call writefile(readfile(temp,'b'),file,'b')
|
939
|
+
endif
|
940
|
+
else
|
941
|
+
execute 'write! '.s:fnameescape(s:repo().translate(path))
|
942
|
+
endif
|
943
|
+
|
944
|
+
let error = s:repo().git_chomp_in_tree('add', file)
|
945
|
+
if v:shell_error
|
946
|
+
let v:errmsg = 'fugitive: '.error
|
947
|
+
return 'echoerr v:errmsg'
|
948
|
+
endif
|
949
|
+
if s:buffer().path() ==# path && s:buffer().commit() =~# '^\d$'
|
950
|
+
set nomodified
|
951
|
+
endif
|
952
|
+
|
953
|
+
let one = s:repo().translate(':1:'.path)
|
954
|
+
let two = s:repo().translate(':2:'.path)
|
955
|
+
let three = s:repo().translate(':3:'.path)
|
956
|
+
for nr in range(1,bufnr('$'))
|
957
|
+
if bufloaded(nr) && !getbufvar(nr,'&modified') && (bufname(nr) == one || bufname(nr) == two || bufname(nr) == three)
|
958
|
+
execute nr.'bdelete'
|
959
|
+
endif
|
960
|
+
endfor
|
961
|
+
|
962
|
+
unlet! restorewinnr
|
963
|
+
let zero = s:repo().translate(':0:'.path)
|
964
|
+
for tab in range(1,tabpagenr('$'))
|
965
|
+
for winnr in range(1,tabpagewinnr(tab,'$'))
|
966
|
+
let bufnr = tabpagebuflist(tab)[winnr-1]
|
967
|
+
let bufname = bufname(bufnr)
|
968
|
+
if bufname ==# zero && bufnr != mybufnr
|
969
|
+
execute 'tabnext '.tab
|
970
|
+
if winnr != winnr()
|
971
|
+
execute winnr.'wincmd w'
|
972
|
+
let restorewinnr = 1
|
973
|
+
endif
|
974
|
+
try
|
975
|
+
let lnum = line('.')
|
976
|
+
let last = line('$')
|
977
|
+
silent $read `=file`
|
978
|
+
silent execute '1,'.last.'delete_'
|
979
|
+
silent execute lnum
|
980
|
+
set nomodified
|
981
|
+
diffupdate
|
982
|
+
finally
|
983
|
+
if exists('restorewinnr')
|
984
|
+
wincmd p
|
985
|
+
endif
|
986
|
+
execute 'tabnext '.mytab
|
987
|
+
endtry
|
988
|
+
break
|
989
|
+
endif
|
990
|
+
endfor
|
991
|
+
endfor
|
992
|
+
call fugitive#reload_status()
|
993
|
+
return 'checktime'
|
994
|
+
endfunction
|
995
|
+
|
996
|
+
" }}}1
|
997
|
+
" Gdiff {{{1
|
998
|
+
|
999
|
+
call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gdiff :execute s:Diff(<f-args>)")
|
1000
|
+
|
1001
|
+
augroup fugitive_diff
|
1002
|
+
autocmd BufWinLeave * if winnr('$') == 2 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | diffoff! | endif
|
1003
|
+
autocmd BufWinEnter * if winnr('$') == 1 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | diffoff | endif
|
1004
|
+
augroup END
|
1005
|
+
|
1006
|
+
function! s:buffer_compare_age(commit) dict abort
|
1007
|
+
let scores = {':0': 1, ':1': 2, ':2': 3, ':': 4, ':3': 5}
|
1008
|
+
let my_score = get(scores,':'.self.commit(),0)
|
1009
|
+
let their_score = get(scores,':'.a:commit,0)
|
1010
|
+
if my_score || their_score
|
1011
|
+
return my_score < their_score ? -1 : my_score != their_score
|
1012
|
+
elseif self.commit() ==# a:commit
|
1013
|
+
return 0
|
1014
|
+
endif
|
1015
|
+
let base = self.repo().git_chomp('merge-base',self.commit(),a:commit)
|
1016
|
+
if base ==# self.commit()
|
1017
|
+
return -1
|
1018
|
+
elseif base ==# a:commit
|
1019
|
+
return 1
|
1020
|
+
endif
|
1021
|
+
let my_time = +self.repo().git_chomp('log','--max-count=1','--pretty=format:%at',self.commit())
|
1022
|
+
let their_time = +self.repo().git_chomp('log','--max-count=1','--pretty=format:%at',a:commit)
|
1023
|
+
return my_time < their_time ? -1 : my_time != their_time
|
1024
|
+
endfunction
|
1025
|
+
|
1026
|
+
call s:add_methods('buffer',['compare_age'])
|
1027
|
+
|
1028
|
+
function! s:Diff(...) abort
|
1029
|
+
if exists(':DiffGitCached')
|
1030
|
+
return 'DiffGitCached'
|
1031
|
+
elseif (!a:0 || a:1 == ':') && s:buffer().commit() =~# '^[0-1]\=$' && s:repo().git_chomp_in_tree('ls-files', '--unmerged', '--', s:buffer().path()) !=# ''
|
1032
|
+
leftabove vsplit `=fugitive#buffer().repo().translate(s:buffer().expand(':2'))`
|
1033
|
+
diffthis
|
1034
|
+
wincmd p
|
1035
|
+
rightbelow vsplit `=fugitive#buffer().repo().translate(s:buffer().expand(':3'))`
|
1036
|
+
diffthis
|
1037
|
+
wincmd p
|
1038
|
+
diffthis
|
1039
|
+
return ''
|
1040
|
+
elseif a:0
|
1041
|
+
if a:1 ==# ''
|
1042
|
+
return ''
|
1043
|
+
elseif a:1 ==# '/'
|
1044
|
+
let file = s:buffer().path('/')
|
1045
|
+
elseif a:1 ==# ':'
|
1046
|
+
let file = s:buffer().path(':0:')
|
1047
|
+
elseif a:1 =~# '^:/'
|
1048
|
+
try
|
1049
|
+
let file = s:repo().rev_parse(a:1).s:buffer().path(':')
|
1050
|
+
catch /^fugitive:/
|
1051
|
+
return 'echoerr v:errmsg'
|
1052
|
+
endtry
|
1053
|
+
else
|
1054
|
+
let file = s:buffer().expand(a:1)
|
1055
|
+
endif
|
1056
|
+
if file !~# ':' && file !~# '^/' && s:repo().git_chomp('cat-file','-t',file) =~# '^\%(tag\|commit\)$'
|
1057
|
+
let file = file.s:buffer().path(':')
|
1058
|
+
endif
|
1059
|
+
else
|
1060
|
+
let file = s:buffer().path(s:buffer().commit() == '' ? ':0:' : '/')
|
1061
|
+
endif
|
1062
|
+
try
|
1063
|
+
let spec = s:repo().translate(file)
|
1064
|
+
let commit = matchstr(spec,'\C[^:/]//\zs\x\+')
|
1065
|
+
if s:buffer().compare_age(commit) < 0
|
1066
|
+
rightbelow vsplit `=spec`
|
1067
|
+
else
|
1068
|
+
leftabove vsplit `=spec`
|
1069
|
+
endif
|
1070
|
+
diffthis
|
1071
|
+
wincmd p
|
1072
|
+
diffthis
|
1073
|
+
return ''
|
1074
|
+
catch /^fugitive:/
|
1075
|
+
return 'echoerr v:errmsg'
|
1076
|
+
endtry
|
1077
|
+
endfunction
|
1078
|
+
|
1079
|
+
" }}}1
|
1080
|
+
" Gmove, Gremove {{{1
|
1081
|
+
|
1082
|
+
function! s:Move(force,destination)
|
1083
|
+
if a:destination =~# '^/'
|
1084
|
+
let destination = a:destination[1:-1]
|
1085
|
+
else
|
1086
|
+
let destination = fnamemodify(s:sub(a:destination,'[%#]%(:\w)*','\=expand(submatch(0))'),':p')
|
1087
|
+
if destination[0:strlen(s:repo().tree())] ==# s:repo().tree('')
|
1088
|
+
let destination = destination[strlen(s:repo().tree('')):-1]
|
1089
|
+
endif
|
1090
|
+
endif
|
1091
|
+
let message = call(s:repo().git_chomp_in_tree,['mv']+(a:force ? ['-f'] : [])+['--', s:buffer().path(), destination], s:repo())
|
1092
|
+
if v:shell_error
|
1093
|
+
let v:errmsg = 'fugitive: '.message
|
1094
|
+
return 'echoerr v:errmsg'
|
1095
|
+
endif
|
1096
|
+
let destination = s:repo().tree(destination)
|
1097
|
+
if isdirectory(destination)
|
1098
|
+
let destination = fnamemodify(s:sub(destination,'/$','').'/'.expand('%:t'),':.')
|
1099
|
+
endif
|
1100
|
+
call fugitive#reload_status()
|
1101
|
+
if s:buffer().commit() == ''
|
1102
|
+
return 'saveas! '.s:fnameescape(destination)
|
1103
|
+
else
|
1104
|
+
return 'file '.s:fnameescape(s:repo().translate(':0:'.destination)
|
1105
|
+
endif
|
1106
|
+
endfunction
|
1107
|
+
|
1108
|
+
function! s:MoveComplete(A,L,P)
|
1109
|
+
if a:A =~ '^/'
|
1110
|
+
return s:repo().superglob(a:A)
|
1111
|
+
else
|
1112
|
+
let matches = split(glob(a:A.'*'),"\n")
|
1113
|
+
call map(matches,'v:val !~ "/$" && isdirectory(v:val) ? v:val."/" : v:val')
|
1114
|
+
return matches
|
1115
|
+
endif
|
1116
|
+
endfunction
|
1117
|
+
|
1118
|
+
function! s:Remove(force)
|
1119
|
+
if s:buffer().commit() ==# ''
|
1120
|
+
let cmd = ['rm']
|
1121
|
+
elseif s:buffer().commit() ==# '0'
|
1122
|
+
let cmd = ['rm','--cached']
|
1123
|
+
else
|
1124
|
+
let v:errmsg = 'fugitive: rm not supported here'
|
1125
|
+
return 'echoerr v:errmsg'
|
1126
|
+
endif
|
1127
|
+
if a:force
|
1128
|
+
let cmd += ['--force']
|
1129
|
+
endif
|
1130
|
+
let message = call(s:repo().git_chomp_in_tree,cmd+['--',s:buffer().path()],s:repo())
|
1131
|
+
if v:shell_error
|
1132
|
+
let v:errmsg = 'fugitive: '.s:sub(message,'error:.*\zs\n\(.*-f.*',' (add ! to force)')
|
1133
|
+
return 'echoerr '.string(v:errmsg)
|
1134
|
+
else
|
1135
|
+
call fugitive#reload_status()
|
1136
|
+
return 'bdelete'.(a:force ? '!' : '')
|
1137
|
+
endif
|
1138
|
+
endfunction
|
1139
|
+
|
1140
|
+
augroup fugitive_remove
|
1141
|
+
autocmd!
|
1142
|
+
autocmd User Fugitive if s:buffer().commit() =~# '^0\=$' |
|
1143
|
+
\ exe "command! -buffer -bar -bang -nargs=1 -complete=customlist,s:MoveComplete Gmove :execute s:Move(<bang>0,<q-args>)" |
|
1144
|
+
\ exe "command! -buffer -bar -bang Gremove :execute s:Remove(<bang>0)" |
|
1145
|
+
\ endif
|
1146
|
+
augroup END
|
1147
|
+
|
1148
|
+
" }}}1
|
1149
|
+
" Gblame {{{1
|
1150
|
+
|
1151
|
+
augroup fugitive_blame
|
1152
|
+
autocmd!
|
1153
|
+
autocmd BufReadPost *.fugitiveblame setfiletype fugitiveblame
|
1154
|
+
autocmd FileType fugitiveblame setlocal nomodeline | if exists('b:git_dir') | let &l:keywordprg = s:repo().keywordprg() | endif
|
1155
|
+
autocmd Syntax fugitiveblame call s:BlameSyntax()
|
1156
|
+
autocmd User Fugitive if s:buffer().type('file', 'blob') | exe "command! -buffer -bar -bang -range=0 -nargs=* Gblame :execute s:Blame(<bang>0,<line1>,<line2>,<count>,[<f-args>])" | endif
|
1157
|
+
augroup END
|
1158
|
+
|
1159
|
+
function! s:Blame(bang,line1,line2,count,args) abort
|
1160
|
+
try
|
1161
|
+
if s:buffer().path() == ''
|
1162
|
+
call s:throw('file or blob required')
|
1163
|
+
endif
|
1164
|
+
if filter(copy(a:args),'v:val !~# "^\\%(--root\|--show-name\\|-\\=\\%([ltwfs]\\|[MC]\\d*\\)\\+\\)$"') != []
|
1165
|
+
call s:throw('unsupported option')
|
1166
|
+
endif
|
1167
|
+
call map(a:args,'s:sub(v:val,"^\\ze[^-]","-")')
|
1168
|
+
let git_dir = s:repo().dir()
|
1169
|
+
let cmd = ['--no-pager', 'blame', '--show-number'] + a:args
|
1170
|
+
if s:buffer().commit() =~# '\D\|..'
|
1171
|
+
let cmd += [s:buffer().commit()]
|
1172
|
+
else
|
1173
|
+
let cmd += ['--contents', '-']
|
1174
|
+
endif
|
1175
|
+
let basecmd = call(s:repo().git_command,cmd+['--',s:buffer().path()],s:repo())
|
1176
|
+
try
|
1177
|
+
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
1178
|
+
if !s:repo().bare()
|
1179
|
+
let dir = getcwd()
|
1180
|
+
execute cd.'`=s:repo().tree()`'
|
1181
|
+
endif
|
1182
|
+
if a:count
|
1183
|
+
execute 'write !'.substitute(basecmd,' blame ',' blame -L '.a:line1.','.a:line2.' ','g')
|
1184
|
+
else
|
1185
|
+
let error = tempname()
|
1186
|
+
let temp = error.'.fugitiveblame'
|
1187
|
+
silent! exe '%write !'.basecmd.' > '.temp.' 2> '.error
|
1188
|
+
if v:shell_error
|
1189
|
+
call s:throw(join(readfile(error),"\n"))
|
1190
|
+
endif
|
1191
|
+
let bufnr = bufnr('')
|
1192
|
+
let restore = 'call setbufvar('.bufnr.',"&scrollbind",0)'
|
1193
|
+
if &l:wrap
|
1194
|
+
let restore .= '|call setbufvar('.bufnr.',"&wrap",1)'
|
1195
|
+
endif
|
1196
|
+
if &l:foldenable
|
1197
|
+
let restore .= '|call setbufvar('.bufnr.',"&foldenable",1)'
|
1198
|
+
endif
|
1199
|
+
let winnr = winnr()
|
1200
|
+
windo set noscrollbind
|
1201
|
+
exe winnr.'wincmd w'
|
1202
|
+
setlocal scrollbind nowrap nofoldenable
|
1203
|
+
let top = line('w0') + &scrolloff
|
1204
|
+
let current = line('.')
|
1205
|
+
exe 'leftabove vsplit '.temp
|
1206
|
+
let b:git_dir = git_dir
|
1207
|
+
let b:fugitive_type = 'blame'
|
1208
|
+
let b:fugitive_blamed_bufnr = bufnr
|
1209
|
+
let b:fugitive_restore = restore
|
1210
|
+
let b:fugitive_blame_arguments = join(a:args,' ')
|
1211
|
+
call s:Detect(expand('%:p'))
|
1212
|
+
execute top
|
1213
|
+
normal! zt
|
1214
|
+
execute current
|
1215
|
+
execute "vertical resize ".(match(getline('.'),'\s\+\d\+)')+1)
|
1216
|
+
setlocal nomodified nomodifiable bufhidden=delete nonumber scrollbind nowrap foldcolumn=0 nofoldenable filetype=fugitiveblame
|
1217
|
+
nnoremap <buffer> <silent> q :<C-U>bdelete<CR>
|
1218
|
+
nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>BlameJump('')<CR>
|
1219
|
+
nnoremap <buffer> <silent> P :<C-U>exe <SID>BlameJump('^'.v:count1)<CR>
|
1220
|
+
nnoremap <buffer> <silent> ~ :<C-U>exe <SID>BlameJump('~'.v:count1)<CR>
|
1221
|
+
nnoremap <buffer> <silent> o :<C-U>exe <SID>Edit((&splitbelow ? "botright" : "topleft")." split", matchstr(getline('.'),'\x\+'))<CR>
|
1222
|
+
nnoremap <buffer> <silent> O :<C-U>exe <SID>Edit("tabedit", matchstr(getline('.'),'\x\+'))<CR>
|
1223
|
+
syncbind
|
1224
|
+
endif
|
1225
|
+
finally
|
1226
|
+
if exists('l:dir')
|
1227
|
+
execute cd.'`=dir`'
|
1228
|
+
endif
|
1229
|
+
endtry
|
1230
|
+
return ''
|
1231
|
+
catch /^fugitive:/
|
1232
|
+
return 'echoerr v:errmsg'
|
1233
|
+
endtry
|
1234
|
+
endfunction
|
1235
|
+
|
1236
|
+
function! s:BlameJump(suffix) abort
|
1237
|
+
let commit = matchstr(getline('.'),'^\^\=\zs\x\+')
|
1238
|
+
if commit =~# '^0\+$'
|
1239
|
+
let commit = ':0'
|
1240
|
+
endif
|
1241
|
+
let lnum = matchstr(getline('.'),'\d\+\ze\s\+[([:digit:]]')
|
1242
|
+
let path = matchstr(getline('.'),'^\^\=\zs\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
|
1243
|
+
if path ==# ''
|
1244
|
+
let path = s:buffer(b:fugitive_blamed_bufnr).path()
|
1245
|
+
endif
|
1246
|
+
let args = b:fugitive_blame_arguments
|
1247
|
+
let offset = line('.') - line('w0')
|
1248
|
+
let bufnr = bufnr('%')
|
1249
|
+
let winnr = bufwinnr(b:fugitive_blamed_bufnr)
|
1250
|
+
if winnr > 0
|
1251
|
+
exe winnr.'wincmd w'
|
1252
|
+
endif
|
1253
|
+
execute s:Edit('edit',commit.a:suffix.':'.path)
|
1254
|
+
if winnr > 0
|
1255
|
+
exe bufnr.'bdelete'
|
1256
|
+
endif
|
1257
|
+
execute 'Gblame '.args
|
1258
|
+
execute lnum
|
1259
|
+
let delta = line('.') - line('w0') - offset
|
1260
|
+
if delta > 0
|
1261
|
+
execute 'norm! 'delta."\<C-E>"
|
1262
|
+
elseif delta < 0
|
1263
|
+
execute 'norm! '(-delta)."\<C-Y>"
|
1264
|
+
endif
|
1265
|
+
syncbind
|
1266
|
+
return ''
|
1267
|
+
endfunction
|
1268
|
+
|
1269
|
+
function! s:BlameSyntax() abort
|
1270
|
+
let b:current_syntax = 'fugitiveblame'
|
1271
|
+
syn match FugitiveblameBoundary "^\^"
|
1272
|
+
syn match FugitiveblameBlank "^\s\+\s\@=" nextgroup=FugitiveblameAnnotation,fugitiveblameOriginalFile,FugitiveblameOriginalLineNumber skipwhite
|
1273
|
+
syn match FugitiveblameHash "\%(^\^\=\)\@<=\x\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
|
1274
|
+
syn match FugitiveblameUncommitted "\%(^\^\=\)\@<=0\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
|
1275
|
+
syn region FugitiveblameAnnotation matchgroup=FugitiveblameDelimiter start="(" end="\%( \d\+\)\@<=)" contained keepend oneline
|
1276
|
+
syn match FugitiveblameTime "[0-9:/+-][0-9:/+ -]*[0-9:/+-]\%( \+\d\+)\)\@=" contained containedin=FugitiveblameAnnotation
|
1277
|
+
syn match FugitiveblameLineNumber " \@<=\d\+)\@=" contained containedin=FugitiveblameAnnotation
|
1278
|
+
syn match FugitiveblameOriginalFile " \%(\f\+\D\@<=\|\D\@=\f\+\)\%(\%(\s\+\d\+\)\=\s\%((\|\s*\d\+)\)\)\@=" contained nextgroup=FugitiveblameOriginalLineNumber,FugitiveblameAnnotation skipwhite
|
1279
|
+
syn match FugitiveblameOriginalLineNumber " \@<=\d\+\%(\s(\)\@=" contained nextgroup=FugitiveblameAnnotation skipwhite
|
1280
|
+
syn match FugitiveblameOriginalLineNumber " \@<=\d\+\%(\s\+\d\+)\)\@=" contained nextgroup=FugitiveblameShort skipwhite
|
1281
|
+
syn match FugitiveblameShort "\d\+)" contained contains=FugitiveblameLineNumber
|
1282
|
+
syn match FugitiveblameNotCommittedYet "(\@<=Not Committed Yet\>" contained containedin=FugitiveblameAnnotation
|
1283
|
+
hi def link FugitiveblameBoundary Keyword
|
1284
|
+
hi def link FugitiveblameHash Identifier
|
1285
|
+
hi def link FugitiveblameUncommitted Function
|
1286
|
+
hi def link FugitiveblameTime PreProc
|
1287
|
+
hi def link FugitiveblameLineNumber Number
|
1288
|
+
hi def link FugitiveblameOriginalFile String
|
1289
|
+
hi def link FugitiveblameOriginalLineNumber Float
|
1290
|
+
hi def link FugitiveblameShort FugitiveblameDelimiter
|
1291
|
+
hi def link FugitiveblameDelimiter Delimiter
|
1292
|
+
hi def link FugitiveblameNotCommittedYet Comment
|
1293
|
+
endfunction
|
1294
|
+
|
1295
|
+
" }}}1
|
1296
|
+
" File access {{{1
|
1297
|
+
|
1298
|
+
function! s:ReplaceCmd(cmd,...) abort
|
1299
|
+
let fn = bufname('')
|
1300
|
+
let tmp = tempname()
|
1301
|
+
let aw = &autowrite
|
1302
|
+
let prefix = ''
|
1303
|
+
try
|
1304
|
+
if a:0 && a:1 != ''
|
1305
|
+
if &shell =~# 'cmd'
|
1306
|
+
let old_index = $GIT_INDEX_FILE
|
1307
|
+
let $GIT_INDEX_FILE = a:1
|
1308
|
+
elseif &shell =~# 'csh'
|
1309
|
+
let prefix = 'setenv GIT_INDEX_FILE '.s:shellesc(a:1).'; '
|
1310
|
+
else
|
1311
|
+
let prefix = 'GIT_INDEX_FILE='.s:shellesc(a:1).' '
|
1312
|
+
endif
|
1313
|
+
endif
|
1314
|
+
set noautowrite
|
1315
|
+
silent exe '!'.escape(prefix.a:cmd,'%#').' > '.tmp
|
1316
|
+
finally
|
1317
|
+
let &autowrite = aw
|
1318
|
+
if exists('old_index')
|
1319
|
+
let $GIT_INDEX_FILE = old_index
|
1320
|
+
endif
|
1321
|
+
endtry
|
1322
|
+
silent exe 'keepalt file '.tmp
|
1323
|
+
silent edit!
|
1324
|
+
silent exe 'keepalt file '.s:fnameescape(fn)
|
1325
|
+
call delete(tmp)
|
1326
|
+
silent exe 'doau BufReadPost '.s:fnameescape(fn)
|
1327
|
+
endfunction
|
1328
|
+
|
1329
|
+
function! s:BufReadIndex()
|
1330
|
+
if !exists('b:fugitive_display_format')
|
1331
|
+
let b:fugitive_display_format = filereadable(expand('%').'.lock')
|
1332
|
+
endif
|
1333
|
+
let b:fugitive_display_format = b:fugitive_display_format % 2
|
1334
|
+
let b:fugitive_type = 'index'
|
1335
|
+
try
|
1336
|
+
let b:git_dir = s:repo().dir()
|
1337
|
+
setlocal noro ma
|
1338
|
+
if fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : b:git_dir . '/index', ':p') ==# expand('%:p')
|
1339
|
+
let index = ''
|
1340
|
+
else
|
1341
|
+
let index = expand('%')
|
1342
|
+
endif
|
1343
|
+
if b:fugitive_display_format
|
1344
|
+
call s:ReplaceCmd(s:repo().git_command('ls-files','--stage'),index)
|
1345
|
+
set ft=git nospell
|
1346
|
+
else
|
1347
|
+
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
1348
|
+
let dir = getcwd()
|
1349
|
+
try
|
1350
|
+
execute cd.'`=s:repo().tree()`'
|
1351
|
+
call s:ReplaceCmd(s:repo().git_command('status'),index)
|
1352
|
+
finally
|
1353
|
+
execute cd.'`=dir`'
|
1354
|
+
endtry
|
1355
|
+
set ft=gitcommit
|
1356
|
+
endif
|
1357
|
+
setlocal ro noma nomod nomodeline bufhidden=delete
|
1358
|
+
nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += 1<Bar>exe <SID>BufReadIndex()<CR>
|
1359
|
+
nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= 1<Bar>exe <SID>BufReadIndex()<CR>
|
1360
|
+
nnoremap <buffer> <silent> D :<C-U>execute <SID>StageDiff()<CR>
|
1361
|
+
nnoremap <buffer> <silent> - :<C-U>execute <SID>StageToggle(line('.'),line('.')+v:count1-1)<CR>
|
1362
|
+
xnoremap <buffer> <silent> - :<C-U>execute <SID>StageToggle(line("'<"),line("'>"))<CR>
|
1363
|
+
nnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR>
|
1364
|
+
xnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line("'<"),line("'>"))<CR>
|
1365
|
+
call s:JumpInit()
|
1366
|
+
nunmap <buffer> P
|
1367
|
+
nunmap <buffer> ~
|
1368
|
+
nnoremap <buffer> <silent> C :<C-U>Gcommit<CR>
|
1369
|
+
catch /^fugitive:/
|
1370
|
+
return 'echoerr v:errmsg'
|
1371
|
+
endtry
|
1372
|
+
endfunction
|
1373
|
+
|
1374
|
+
function! s:FileRead()
|
1375
|
+
try
|
1376
|
+
let repo = s:repo(s:ExtractGitDir(expand('<amatch>')))
|
1377
|
+
let path = s:sub(s:sub(matchstr(expand('<amatch>'),'fugitive://.\{-\}//\zs.*'),'/',':'),'^\d:',':&')
|
1378
|
+
let hash = repo.rev_parse(path)
|
1379
|
+
if path =~ '^:'
|
1380
|
+
let type = 'blob'
|
1381
|
+
else
|
1382
|
+
let type = repo.git_chomp('cat-file','-t',hash)
|
1383
|
+
endif
|
1384
|
+
" TODO: use count, if possible
|
1385
|
+
return "read !".escape(repo.git_command('cat-file',type,hash),'%#\')
|
1386
|
+
catch /^fugitive:/
|
1387
|
+
return 'echoerr v:errmsg'
|
1388
|
+
endtry
|
1389
|
+
endfunction
|
1390
|
+
|
1391
|
+
function! s:BufReadIndexFile()
|
1392
|
+
try
|
1393
|
+
let b:fugitive_type = 'blob'
|
1394
|
+
let b:git_dir = s:repo().dir()
|
1395
|
+
call s:ReplaceCmd(s:repo().git_command('cat-file','blob',s:buffer().sha1()))
|
1396
|
+
return ''
|
1397
|
+
catch /^fugitive: rev-parse/
|
1398
|
+
silent exe 'doau BufNewFile '.s:fnameescape(bufname(''))
|
1399
|
+
return ''
|
1400
|
+
catch /^fugitive:/
|
1401
|
+
return 'echoerr v:errmsg'
|
1402
|
+
endtry
|
1403
|
+
endfunction
|
1404
|
+
|
1405
|
+
function! s:BufWriteIndexFile()
|
1406
|
+
let tmp = tempname()
|
1407
|
+
try
|
1408
|
+
let path = matchstr(expand('<amatch>'),'//\d/\zs.*')
|
1409
|
+
let stage = matchstr(expand('<amatch>'),'//\zs\d')
|
1410
|
+
silent execute 'write !'.s:repo().git_command('hash-object','-w','--stdin').' > '.tmp
|
1411
|
+
let sha1 = readfile(tmp)[0]
|
1412
|
+
let old_mode = matchstr(s:repo().git_chomp('ls-files','--stage',path),'^\d\+')
|
1413
|
+
if old_mode == ''
|
1414
|
+
let old_mode = executable(s:repo().tree(path)) ? '100755' : '100644'
|
1415
|
+
endif
|
1416
|
+
let info = old_mode.' '.sha1.' '.stage."\t".path
|
1417
|
+
call writefile([info],tmp)
|
1418
|
+
let error = system(s:repo().git_command('update-index','--index-info').' < '.tmp)
|
1419
|
+
if v:shell_error == 0
|
1420
|
+
setlocal nomodified
|
1421
|
+
silent execute 'doautocmd BufWritePost '.s:fnameescape(expand('%:p'))
|
1422
|
+
call fugitive#reload_status()
|
1423
|
+
return ''
|
1424
|
+
else
|
1425
|
+
return 'echoerr '.string('fugitive: '.error)
|
1426
|
+
endif
|
1427
|
+
finally
|
1428
|
+
call delete(tmp)
|
1429
|
+
endtry
|
1430
|
+
endfunction
|
1431
|
+
|
1432
|
+
function! s:BufReadObject()
|
1433
|
+
try
|
1434
|
+
setlocal noro ma
|
1435
|
+
let b:git_dir = s:repo().dir()
|
1436
|
+
let hash = s:buffer().sha1()
|
1437
|
+
if !exists("b:fugitive_type")
|
1438
|
+
let b:fugitive_type = s:repo().git_chomp('cat-file','-t',hash)
|
1439
|
+
endif
|
1440
|
+
if b:fugitive_type !~# '^\%(tag\|commit\|tree\|blob\)$'
|
1441
|
+
return "echoerr 'fugitive: unrecognized git type'"
|
1442
|
+
endif
|
1443
|
+
let firstline = getline('.')
|
1444
|
+
if !exists('b:fugitive_display_format') && b:fugitive_type != 'blob'
|
1445
|
+
let b:fugitive_display_format = +getbufvar('#','fugitive_display_format')
|
1446
|
+
endif
|
1447
|
+
|
1448
|
+
let pos = getpos('.')
|
1449
|
+
silent %delete
|
1450
|
+
setlocal endofline
|
1451
|
+
|
1452
|
+
if b:fugitive_type == 'tree'
|
1453
|
+
let b:fugitive_display_format = b:fugitive_display_format % 2
|
1454
|
+
if b:fugitive_display_format
|
1455
|
+
call s:ReplaceCmd(s:repo().git_command('ls-tree',hash))
|
1456
|
+
else
|
1457
|
+
call s:ReplaceCmd(s:repo().git_command('show',hash))
|
1458
|
+
endif
|
1459
|
+
elseif b:fugitive_type == 'tag'
|
1460
|
+
let b:fugitive_display_format = b:fugitive_display_format % 2
|
1461
|
+
if b:fugitive_display_format
|
1462
|
+
call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
|
1463
|
+
else
|
1464
|
+
call s:ReplaceCmd(s:repo().git_command('cat-file','-p',hash))
|
1465
|
+
endif
|
1466
|
+
elseif b:fugitive_type == 'commit'
|
1467
|
+
let b:fugitive_display_format = b:fugitive_display_format % 2
|
1468
|
+
if b:fugitive_display_format
|
1469
|
+
call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
|
1470
|
+
else
|
1471
|
+
call s:ReplaceCmd(s:repo().git_command('show','--pretty=format:tree %T%nparent %P%nauthor %an <%ae> %ad%ncommitter %cn <%ce> %cd%nencoding %e%n%n%s%n%n%b',hash))
|
1472
|
+
call search('^parent ')
|
1473
|
+
if getline('.') ==# 'parent '
|
1474
|
+
silent delete_
|
1475
|
+
else
|
1476
|
+
silent s/\%(^parent\)\@<! /\rparent /ge
|
1477
|
+
endif
|
1478
|
+
if search('^encoding \%(<unknown>\)\=$','W',line('.')+3)
|
1479
|
+
silent delete_
|
1480
|
+
end
|
1481
|
+
1
|
1482
|
+
endif
|
1483
|
+
elseif b:fugitive_type ==# 'blob'
|
1484
|
+
call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
|
1485
|
+
endif
|
1486
|
+
call setpos('.',pos)
|
1487
|
+
setlocal ro noma nomod nomodeline
|
1488
|
+
if b:fugitive_type !=# 'blob'
|
1489
|
+
set filetype=git
|
1490
|
+
nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += v:count1<Bar>exe <SID>BufReadObject()<CR>
|
1491
|
+
nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= v:count1<Bar>exe <SID>BufReadObject()<CR>
|
1492
|
+
else
|
1493
|
+
call s:JumpInit()
|
1494
|
+
endif
|
1495
|
+
|
1496
|
+
return ''
|
1497
|
+
catch /^fugitive:/
|
1498
|
+
return 'echoerr v:errmsg'
|
1499
|
+
endtry
|
1500
|
+
endfunction
|
1501
|
+
|
1502
|
+
augroup fugitive_files
|
1503
|
+
autocmd!
|
1504
|
+
autocmd BufReadCmd *.git/index exe s:BufReadIndex()
|
1505
|
+
autocmd BufReadCmd *.git/*index*.lock exe s:BufReadIndex()
|
1506
|
+
autocmd FileReadCmd fugitive://**//[0-3]/** exe s:FileRead()
|
1507
|
+
autocmd BufReadCmd fugitive://**//[0-3]/** exe s:BufReadIndexFile()
|
1508
|
+
autocmd BufWriteCmd fugitive://**//[0-3]/** exe s:BufWriteIndexFile()
|
1509
|
+
autocmd BufReadCmd fugitive://**//[0-9a-f][0-9a-f]* exe s:BufReadObject()
|
1510
|
+
autocmd FileReadCmd fugitive://**//[0-9a-f][0-9a-f]* exe s:FileRead()
|
1511
|
+
autocmd FileType git call s:JumpInit()
|
1512
|
+
augroup END
|
1513
|
+
|
1514
|
+
" }}}1
|
1515
|
+
" Go to file {{{1
|
1516
|
+
|
1517
|
+
function! s:JumpInit() abort
|
1518
|
+
nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>GF("edit")<CR>
|
1519
|
+
if !&modifiable
|
1520
|
+
nnoremap <buffer> <silent> o :<C-U>exe <SID>GF("split")<CR>
|
1521
|
+
nnoremap <buffer> <silent> O :<C-U>exe <SID>GF("tabedit")<CR>
|
1522
|
+
nnoremap <buffer> <silent> P :<C-U>exe <SID>Edit('edit',<SID>buffer().commit().'^'.v:count1.<SID>buffer().path(':'))<CR>
|
1523
|
+
nnoremap <buffer> <silent> ~ :<C-U>exe <SID>Edit('edit',<SID>buffer().commit().'~'.v:count1.<SID>buffer().path(':'))<CR>
|
1524
|
+
nnoremap <buffer> <silent> C :<C-U>exe <SID>Edit('edit',<SID>buffer().containing_commit())<CR>
|
1525
|
+
nnoremap <buffer> <silent> cc :<C-U>exe <SID>Edit('edit',<SID>buffer().containing_commit())<CR>
|
1526
|
+
nnoremap <buffer> <silent> co :<C-U>exe <SID>Edit('split',<SID>buffer().containing_commit())<CR>
|
1527
|
+
nnoremap <buffer> <silent> cO :<C-U>exe <SID>Edit('tabedit',<SID>buffer().containing_commit())<CR>
|
1528
|
+
nnoremap <buffer> <silent> cp :<C-U>exe <SID>Edit('pedit',<SID>buffer().containing_commit())<CR>
|
1529
|
+
endif
|
1530
|
+
endfunction
|
1531
|
+
|
1532
|
+
function! s:GF(mode) abort
|
1533
|
+
try
|
1534
|
+
let buffer = s:buffer()
|
1535
|
+
let myhash = buffer.sha1()
|
1536
|
+
|
1537
|
+
if buffer.type('tree')
|
1538
|
+
let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
|
1539
|
+
if showtree && line('.') == 1
|
1540
|
+
return ""
|
1541
|
+
elseif showtree && line('.') > 2
|
1542
|
+
return s:Edit(a:mode,buffer.commit().':'.(buffer.path() == '' ? '' : buffer.path().'/').s:sub(getline('.'),'/$',''))
|
1543
|
+
elseif getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
|
1544
|
+
return s:Edit(a:mode,buffer.commit().':'.(buffer.path() == '' ? '' : buffer.path().'/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$',''))
|
1545
|
+
endif
|
1546
|
+
|
1547
|
+
elseif buffer.type('blob')
|
1548
|
+
let ref = expand("<cfile>")
|
1549
|
+
try
|
1550
|
+
let sha1 = buffer.repo().rev_parse(ref)
|
1551
|
+
catch /^fugitive:/
|
1552
|
+
endtry
|
1553
|
+
if exists('sha1')
|
1554
|
+
return s:Edit(a:mode,ref)
|
1555
|
+
endif
|
1556
|
+
|
1557
|
+
else
|
1558
|
+
|
1559
|
+
" Index
|
1560
|
+
if getline('.') =~# '^\d\{6\} \x\{40\} \d\t'
|
1561
|
+
let ref = matchstr(getline('.'),'\x\{40\}')
|
1562
|
+
let file = ':'.s:sub(matchstr(getline('.'),'\d\t.*'),'\t',':')
|
1563
|
+
return s:Edit(a:mode,file)
|
1564
|
+
|
1565
|
+
elseif getline('.') =~# '^#\trenamed:.* -> '
|
1566
|
+
let file = '/'.matchstr(getline('.'),' -> \zs.*')
|
1567
|
+
return s:Edit(a:mode,file)
|
1568
|
+
elseif getline('.') =~# '^#\t[[:alpha:] ]\+: *.'
|
1569
|
+
let file = '/'.matchstr(getline('.'),': *\zs.*')
|
1570
|
+
return s:Edit(a:mode,file)
|
1571
|
+
elseif getline('.') =~# '^#\t.'
|
1572
|
+
let file = '/'.matchstr(getline('.'),'#\t\zs.*')
|
1573
|
+
return s:Edit(a:mode,file)
|
1574
|
+
elseif getline('.') =~# ': needs merge$'
|
1575
|
+
let file = '/'.matchstr(getline('.'),'.*\ze: needs merge$')
|
1576
|
+
return s:Edit(a:mode,file).'|Gdiff'
|
1577
|
+
|
1578
|
+
elseif getline('.') ==# '# Not currently on any branch.'
|
1579
|
+
return s:Edit(a:mode,'HEAD')
|
1580
|
+
elseif getline('.') =~# '^# On branch '
|
1581
|
+
let file = 'refs/heads/'.getline('.')[12:]
|
1582
|
+
return s:Edit(a:mode,file)
|
1583
|
+
elseif getline('.') =~# "^# Your branch .*'"
|
1584
|
+
let file = matchstr(getline('.'),"'\\zs\\S\\+\\ze'")
|
1585
|
+
return s:Edit(a:mode,file)
|
1586
|
+
endif
|
1587
|
+
|
1588
|
+
let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
|
1589
|
+
|
1590
|
+
if getline('.') =~# '^ref: '
|
1591
|
+
let ref = strpart(getline('.'),5)
|
1592
|
+
|
1593
|
+
elseif getline('.') =~# '^parent \x\{40\}\>'
|
1594
|
+
let ref = matchstr(getline('.'),'\x\{40\}')
|
1595
|
+
let line = line('.')
|
1596
|
+
let parent = 0
|
1597
|
+
while getline(line) =~# '^parent '
|
1598
|
+
let parent += 1
|
1599
|
+
let line -= 1
|
1600
|
+
endwhile
|
1601
|
+
return s:Edit(a:mode,ref)
|
1602
|
+
|
1603
|
+
elseif getline('.') =~ '^tree \x\{40\}$'
|
1604
|
+
let ref = matchstr(getline('.'),'\x\{40\}')
|
1605
|
+
if s:repo().rev_parse(myhash.':') == ref
|
1606
|
+
let ref = myhash.':'
|
1607
|
+
endif
|
1608
|
+
return s:Edit(a:mode,ref)
|
1609
|
+
|
1610
|
+
elseif getline('.') =~# '^object \x\{40\}$' && getline(line('.')+1) =~ '^type \%(commit\|tree\|blob\)$'
|
1611
|
+
let ref = matchstr(getline('.'),'\x\{40\}')
|
1612
|
+
let type = matchstr(getline(line('.')+1),'type \zs.*')
|
1613
|
+
|
1614
|
+
elseif getline('.') =~# '^\l\{3,8\} '.myhash.'$'
|
1615
|
+
return ''
|
1616
|
+
|
1617
|
+
elseif getline('.') =~# '^\l\{3,8\} \x\{40\}\>'
|
1618
|
+
let ref = matchstr(getline('.'),'\x\{40\}')
|
1619
|
+
echoerr "warning: unknown context ".matchstr(getline('.'),'^\l*')
|
1620
|
+
|
1621
|
+
elseif getline('.') =~# '^[+-]\{3\} [ab/]'
|
1622
|
+
let ref = getline('.')[4:]
|
1623
|
+
|
1624
|
+
elseif getline('.') =~# '^rename from '
|
1625
|
+
let ref = 'a/'.getline('.')[12:]
|
1626
|
+
elseif getline('.') =~# '^rename to '
|
1627
|
+
let ref = 'b/'.getline('.')[10:]
|
1628
|
+
|
1629
|
+
elseif getline('.') =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)'
|
1630
|
+
let dref = matchstr(getline('.'),'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
|
1631
|
+
let ref = matchstr(getline('.'),'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
|
1632
|
+
|
1633
|
+
elseif line('$') == 1 && getline('.') =~ '^\x\{40\}$'
|
1634
|
+
let ref = getline('.')
|
1635
|
+
else
|
1636
|
+
let ref = ''
|
1637
|
+
endif
|
1638
|
+
|
1639
|
+
if myhash ==# ''
|
1640
|
+
let ref = s:sub(ref,'^a/','HEAD:')
|
1641
|
+
let ref = s:sub(ref,'^b/',':0:')
|
1642
|
+
if exists('dref')
|
1643
|
+
let dref = s:sub(dref,'^a/','HEAD:')
|
1644
|
+
endif
|
1645
|
+
else
|
1646
|
+
let ref = s:sub(ref,'^a/',myhash.'^:')
|
1647
|
+
let ref = s:sub(ref,'^b/',myhash.':')
|
1648
|
+
if exists('dref')
|
1649
|
+
let dref = s:sub(dref,'^a/',myhash.'^:')
|
1650
|
+
endif
|
1651
|
+
endif
|
1652
|
+
|
1653
|
+
if ref ==# '/dev/null'
|
1654
|
+
" Empty blob
|
1655
|
+
let ref = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'
|
1656
|
+
endif
|
1657
|
+
|
1658
|
+
if exists('dref')
|
1659
|
+
return s:Edit(a:mode,ref) . '|Gdiff '.s:fnameescape(dref)
|
1660
|
+
elseif ref != ""
|
1661
|
+
return s:Edit(a:mode,ref)
|
1662
|
+
endif
|
1663
|
+
|
1664
|
+
endif
|
1665
|
+
return ''
|
1666
|
+
catch /^fugitive:/
|
1667
|
+
return 'echoerr v:errmsg'
|
1668
|
+
endtry
|
1669
|
+
endfunction
|
1670
|
+
|
1671
|
+
" }}}1
|
1672
|
+
" Statusline {{{1
|
1673
|
+
|
1674
|
+
function! s:repo_head_ref() dict abort
|
1675
|
+
return readfile(s:repo().dir('HEAD'))[0]
|
1676
|
+
endfunction
|
1677
|
+
|
1678
|
+
call s:add_methods('repo',['head_ref'])
|
1679
|
+
|
1680
|
+
function! fugitive#statusline(...)
|
1681
|
+
if !exists('b:git_dir')
|
1682
|
+
return ''
|
1683
|
+
endif
|
1684
|
+
let status = ''
|
1685
|
+
if s:buffer().commit() != ''
|
1686
|
+
let status .= ':' . s:buffer().commit()[0:7]
|
1687
|
+
endif
|
1688
|
+
let head = s:repo().head_ref()
|
1689
|
+
if head =~# '^ref: '
|
1690
|
+
let status .= s:sub(head,'^ref: %(refs/%(heads/|remotes/|tags/)=)=','(').')'
|
1691
|
+
elseif head =~# '^\x\{40\}$'
|
1692
|
+
let status .= '('.head[0:7].')'
|
1693
|
+
endif
|
1694
|
+
if &statusline =~# '%[MRHWY]' && &statusline !~# '%[mrhwy]'
|
1695
|
+
return ',GIT'.status
|
1696
|
+
else
|
1697
|
+
return '[Git'.status.']'
|
1698
|
+
endif
|
1699
|
+
endfunction
|
1700
|
+
|
1701
|
+
" }}}1
|
1702
|
+
|
1703
|
+
" vim:set ft=vim ts=8 sw=2 sts=2:
|