utils 0.0.67 → 0.0.68

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/VERSION +1 -1
  2. data/bin/edit +3 -1
  3. data/lib/utils/editor.rb +14 -0
  4. data/lib/utils/version.rb +1 -1
  5. data/utils.gemspec +3 -3
  6. metadata +3 -74
  7. data/lib/utils/config/vim/after/syntax/haml.vim +0 -9
  8. data/lib/utils/config/vim/after/syntax/html.vim +0 -11
  9. data/lib/utils/config/vim/autoload/Align.vim +0 -1029
  10. data/lib/utils/config/vim/autoload/AlignMaps.vim +0 -330
  11. data/lib/utils/config/vim/autoload/ctrlp/bookmarkdir.vim +0 -139
  12. data/lib/utils/config/vim/autoload/ctrlp/buffertag.vim +0 -238
  13. data/lib/utils/config/vim/autoload/ctrlp/changes.vim +0 -96
  14. data/lib/utils/config/vim/autoload/ctrlp/dir.vim +0 -90
  15. data/lib/utils/config/vim/autoload/ctrlp/line.vim +0 -63
  16. data/lib/utils/config/vim/autoload/ctrlp/mixed.vim +0 -83
  17. data/lib/utils/config/vim/autoload/ctrlp/mrufiles.vim +0 -119
  18. data/lib/utils/config/vim/autoload/ctrlp/quickfix.vim +0 -62
  19. data/lib/utils/config/vim/autoload/ctrlp/rtscript.vim +0 -49
  20. data/lib/utils/config/vim/autoload/ctrlp/tag.vim +0 -112
  21. data/lib/utils/config/vim/autoload/ctrlp/undo.vim +0 -154
  22. data/lib/utils/config/vim/autoload/ctrlp/utils.vim +0 -72
  23. data/lib/utils/config/vim/autoload/ctrlp.vim +0 -1772
  24. data/lib/utils/config/vim/autoload/rails.vim +0 -4570
  25. data/lib/utils/config/vim/autoload/rubycomplete.vim +0 -801
  26. data/lib/utils/config/vim/autoload/sqlcomplete.vim +0 -741
  27. data/lib/utils/config/vim/autoload/vimball.vim +0 -750
  28. data/lib/utils/config/vim/colors/flori.vim +0 -116
  29. data/lib/utils/config/vim/compiler/coffee.vim +0 -68
  30. data/lib/utils/config/vim/compiler/eruby.vim +0 -40
  31. data/lib/utils/config/vim/compiler/ruby.vim +0 -67
  32. data/lib/utils/config/vim/compiler/rubyunit.vim +0 -34
  33. data/lib/utils/config/vim/doc/Decho.txt +0 -372
  34. data/lib/utils/config/vim/doc/coffee-script.txt +0 -116
  35. data/lib/utils/config/vim/doc/ctrlp.txt +0 -1113
  36. data/lib/utils/config/vim/doc/fugitive.txt +0 -257
  37. data/lib/utils/config/vim/doc/rails.txt +0 -1022
  38. data/lib/utils/config/vim/doc/xml-plugin.txt +0 -226
  39. data/lib/utils/config/vim/ftdetect/coffee.vim +0 -8
  40. data/lib/utils/config/vim/ftdetect/eco.vim +0 -1
  41. data/lib/utils/config/vim/ftdetect/ragel.vim +0 -2
  42. data/lib/utils/config/vim/ftdetect/ruby.vim +0 -17
  43. data/lib/utils/config/vim/ftdetect/slim.vim +0 -2
  44. data/lib/utils/config/vim/ftplugin/coffee.vim +0 -221
  45. data/lib/utils/config/vim/ftplugin/eruby.vim +0 -100
  46. data/lib/utils/config/vim/ftplugin/ruby.vim +0 -260
  47. data/lib/utils/config/vim/ftplugin/xml.vim +0 -941
  48. data/lib/utils/config/vim/indent/IndentAnything_html.vim +0 -35
  49. data/lib/utils/config/vim/indent/coffee.vim +0 -338
  50. data/lib/utils/config/vim/indent/eruby.vim +0 -77
  51. data/lib/utils/config/vim/indent/javascript.vim +0 -116
  52. data/lib/utils/config/vim/indent/ruby.vim +0 -377
  53. data/lib/utils/config/vim/indent/slim.vim +0 -75
  54. data/lib/utils/config/vim/plugin/AlignMapsPlugin.vim +0 -242
  55. data/lib/utils/config/vim/plugin/AlignPlugin.vim +0 -41
  56. data/lib/utils/config/vim/plugin/Decho.vim +0 -592
  57. data/lib/utils/config/vim/plugin/IndentAnything.vim +0 -675
  58. data/lib/utils/config/vim/plugin/bufexplorer.vim +0 -1144
  59. data/lib/utils/config/vim/plugin/cecutil.vim +0 -508
  60. data/lib/utils/config/vim/plugin/ctrlp.vim +0 -61
  61. data/lib/utils/config/vim/plugin/fugitive.vim +0 -2041
  62. data/lib/utils/config/vim/plugin/lusty-explorer.vim +0 -1509
  63. data/lib/utils/config/vim/plugin/rails.vim +0 -339
  64. data/lib/utils/config/vim/plugin/rubyextra.vim +0 -193
  65. data/lib/utils/config/vim/plugin/surround.vim +0 -628
  66. data/lib/utils/config/vim/plugin/taglist.vim +0 -4546
  67. data/lib/utils/config/vim/plugin/test/IndentAnything/test.js +0 -131
  68. data/lib/utils/config/vim/plugin/vimballPlugin.vim +0 -40
  69. data/lib/utils/config/vim/syntax/Decho.vim +0 -101
  70. data/lib/utils/config/vim/syntax/coffee.vim +0 -217
  71. data/lib/utils/config/vim/syntax/eco.vim +0 -62
  72. data/lib/utils/config/vim/syntax/eruby.vim +0 -73
  73. data/lib/utils/config/vim/syntax/javascript.vim +0 -246
  74. data/lib/utils/config/vim/syntax/ragel.vim +0 -165
  75. data/lib/utils/config/vim/syntax/ruby.vim +0 -367
  76. data/lib/utils/config/vim/syntax/slim.vim +0 -117
  77. data/lib/utils/config/vimrc +0 -540
@@ -1,2041 +0,0 @@
1
- " fugitive.vim - A Git wrapper so awesome, it should be illegal
2
- " Maintainer: Tim Pope <vimNOSPAM@tpope.org>
3
- " Version: 1.2
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 filereadable(fn . '/.git/HEAD')
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
- let buffer = fugitive#buffer()
136
- if expand('%:p') =~# '//'
137
- call buffer.setvar('&path',s:sub(buffer.getvar('&path'),'^\.%(,|$)',''))
138
- endif
139
- if b:git_dir !~# ',' && stridx(buffer.getvar('&tags'),b:git_dir.'/tags') == -1
140
- if &filetype != ''
141
- call buffer.setvar('&tags',buffer.getvar('&tags').','.b:git_dir.'/'.&filetype.'.tags')
142
- endif
143
- call buffer.setvar('&tags',buffer.getvar('&tags').','.b:git_dir.'/tags')
144
- endif
145
- endif
146
- endfunction
147
-
148
- augroup fugitive
149
- autocmd!
150
- autocmd BufNewFile,BufReadPost * call s:Detect(expand('<amatch>:p'))
151
- autocmd FileType netrw call s:Detect(expand('<afile>:p'))
152
- autocmd VimEnter * if expand('<amatch>')==''|call s:Detect(getcwd())|endif
153
- autocmd BufWinLeave * execute getwinvar(+winnr(), 'fugitive_restore')
154
- augroup END
155
-
156
- " }}}1
157
- " Repository {{{1
158
-
159
- let s:repo_prototype = {}
160
- let s:repos = {}
161
-
162
- function! s:repo(...) abort
163
- let dir = a:0 ? a:1 : (exists('b:git_dir') && b:git_dir !=# '' ? b:git_dir : s:ExtractGitDir(expand('%:p')))
164
- if dir !=# ''
165
- if has_key(s:repos,dir)
166
- let repo = get(s:repos,dir)
167
- else
168
- let repo = {'git_dir': dir}
169
- let s:repos[dir] = repo
170
- endif
171
- return extend(extend(repo,s:repo_prototype,'keep'),s:abstract_prototype,'keep')
172
- endif
173
- call s:throw('not a git repository: '.expand('%:p'))
174
- endfunction
175
-
176
- function! s:repo_dir(...) dict abort
177
- return join([self.git_dir]+a:000,'/')
178
- endfunction
179
-
180
- function! s:repo_tree(...) dict abort
181
- if !self.bare()
182
- let dir = fnamemodify(self.git_dir,':h')
183
- return join([dir]+a:000,'/')
184
- endif
185
- call s:throw('no work tree')
186
- endfunction
187
-
188
- function! s:repo_bare() dict abort
189
- return self.dir() !~# '/\.git$'
190
- endfunction
191
-
192
- function! s:repo_translate(spec) dict abort
193
- if a:spec ==# '.' || a:spec ==# '/.'
194
- return self.bare() ? self.dir() : self.tree()
195
- elseif a:spec =~# '^/'
196
- return fnamemodify(self.dir(),':h').a:spec
197
- elseif a:spec =~# '^:[0-3]:'
198
- return 'fugitive://'.self.dir().'//'.a:spec[1].'/'.a:spec[3:-1]
199
- elseif a:spec ==# ':'
200
- if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(s:repo().dir())] ==# s:repo().dir('') && filereadable($GIT_INDEX_FILE)
201
- return fnamemodify($GIT_INDEX_FILE,':p')
202
- else
203
- return self.dir('index')
204
- endif
205
- elseif a:spec =~# '^:/'
206
- let ref = self.rev_parse(matchstr(a:spec,'.[^:]*'))
207
- return 'fugitive://'.self.dir().'//'.ref
208
- elseif a:spec =~# '^:'
209
- return 'fugitive://'.self.dir().'//0/'.a:spec[1:-1]
210
- elseif a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(self.dir(a:spec))
211
- return self.dir(a:spec)
212
- elseif filereadable(s:repo().dir('refs/'.a:spec))
213
- return self.dir('refs/'.a:spec)
214
- elseif filereadable(s:repo().dir('refs/tags/'.a:spec))
215
- return self.dir('refs/tags/'.a:spec)
216
- elseif filereadable(s:repo().dir('refs/heads/'.a:spec))
217
- return self.dir('refs/heads/'.a:spec)
218
- elseif filereadable(s:repo().dir('refs/remotes/'.a:spec))
219
- return self.dir('refs/remotes/'.a:spec)
220
- elseif filereadable(s:repo().dir('refs/remotes/'.a:spec.'/HEAD'))
221
- return self.dir('refs/remotes/'.a:spec,'/HEAD')
222
- else
223
- try
224
- let ref = self.rev_parse(matchstr(a:spec,'[^:]*'))
225
- let path = s:sub(matchstr(a:spec,':.*'),'^:','/')
226
- return 'fugitive://'.self.dir().'//'.ref.path
227
- catch /^fugitive:/
228
- return self.tree(a:spec)
229
- endtry
230
- endif
231
- endfunction
232
-
233
- call s:add_methods('repo',['dir','tree','bare','translate'])
234
-
235
- function! s:repo_git_command(...) dict abort
236
- let git = g:fugitive_git_executable . ' --git-dir='.s:shellesc(self.git_dir)
237
- return git.join(map(copy(a:000),'" ".s:shellesc(v:val)'),'')
238
- endfunction
239
-
240
- function! s:repo_git_chomp(...) dict abort
241
- return s:sub(system(call(self.git_command,a:000,self)),'\n$','')
242
- endfunction
243
-
244
- function! s:repo_git_chomp_in_tree(...) dict abort
245
- let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
246
- let dir = getcwd()
247
- try
248
- execute cd.'`=s:repo().tree()`'
249
- return call(s:repo().git_chomp, a:000, s:repo())
250
- finally
251
- execute cd.'`=dir`'
252
- endtry
253
- endfunction
254
-
255
- function! s:repo_rev_parse(rev) dict abort
256
- let hash = self.git_chomp('rev-parse','--verify',a:rev)
257
- if hash =~ '\<\x\{40\}$'
258
- return matchstr(hash,'\<\x\{40\}$')
259
- endif
260
- call s:throw('rev-parse '.a:rev.': '.hash)
261
- endfunction
262
-
263
- call s:add_methods('repo',['git_command','git_chomp','git_chomp_in_tree','rev_parse'])
264
-
265
- function! s:repo_dirglob(base) dict abort
266
- let base = s:sub(a:base,'^/','')
267
- let matches = split(glob(self.tree(s:gsub(base,'/','*&').'*/')),"\n")
268
- call map(matches,'v:val[ strlen(self.tree())+(a:base !~ "^/") : -1 ]')
269
- return matches
270
- endfunction
271
-
272
- function! s:repo_superglob(base) dict abort
273
- if a:base =~# '^/' || a:base !~# ':'
274
- let results = []
275
- if a:base !~# '^/'
276
- let heads = ["HEAD","ORIG_HEAD","FETCH_HEAD","MERGE_HEAD"]
277
- let heads += sort(split(s:repo().git_chomp("rev-parse","--symbolic","--branches","--tags","--remotes"),"\n"))
278
- call filter(heads,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
279
- let results += heads
280
- endif
281
- if !self.bare()
282
- let base = s:sub(a:base,'^/','')
283
- let matches = split(glob(self.tree(s:gsub(base,'/','*&').'*')),"\n")
284
- call map(matches,'s:shellslash(v:val)')
285
- call map(matches,'v:val !~ "/$" && isdirectory(v:val) ? v:val."/" : v:val')
286
- call map(matches,'v:val[ strlen(self.tree())+(a:base !~ "^/") : -1 ]')
287
- let results += matches
288
- endif
289
- return results
290
-
291
- elseif a:base =~# '^:'
292
- let entries = split(self.git_chomp('ls-files','--stage'),"\n")
293
- call map(entries,'s:sub(v:val,".*(\\d)\\t(.*)",":\\1:\\2")')
294
- if a:base !~# '^:[0-3]\%(:\|$\)'
295
- call filter(entries,'v:val[1] == "0"')
296
- call map(entries,'v:val[2:-1]')
297
- endif
298
- call filter(entries,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
299
- return entries
300
-
301
- else
302
- let tree = matchstr(a:base,'.*[:/]')
303
- let entries = split(self.git_chomp('ls-tree',tree),"\n")
304
- call map(entries,'s:sub(v:val,"^04.*\\zs$","/")')
305
- call map(entries,'tree.s:sub(v:val,".*\t","")')
306
- return filter(entries,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
307
- endif
308
- endfunction
309
-
310
- call s:add_methods('repo',['dirglob','superglob'])
311
-
312
- function! s:repo_keywordprg() dict abort
313
- let args = ' --git-dir='.escape(self.dir(),"\\\"' ").' show'
314
- if has('gui_running') && !has('win32')
315
- return g:fugitive_git_executable . ' --no-pager' . args
316
- else
317
- return g:fugitive_git_executable . args
318
- endif
319
- endfunction
320
-
321
- call s:add_methods('repo',['keywordprg'])
322
-
323
- " }}}1
324
- " Buffer {{{1
325
-
326
- let s:buffer_prototype = {}
327
-
328
- function! s:buffer(...) abort
329
- let buffer = {'#': bufnr(a:0 ? a:1 : '%')}
330
- call extend(extend(buffer,s:buffer_prototype,'keep'),s:abstract_prototype,'keep')
331
- if buffer.getvar('git_dir') !=# ''
332
- return buffer
333
- endif
334
- call s:throw('not a git repository: '.expand('%:p'))
335
- endfunction
336
-
337
- function! fugitive#buffer(...) abort
338
- return s:buffer(a:0 ? a:1 : '%')
339
- endfunction
340
-
341
- function! s:buffer_getvar(var) dict abort
342
- return getbufvar(self['#'],a:var)
343
- endfunction
344
-
345
- function! s:buffer_setvar(var,value) dict abort
346
- return setbufvar(self['#'],a:var,a:value)
347
- endfunction
348
-
349
- function! s:buffer_getline(lnum) dict abort
350
- return getbufline(self['#'],a:lnum)[0]
351
- endfunction
352
-
353
- function! s:buffer_repo() dict abort
354
- return s:repo(self.getvar('git_dir'))
355
- endfunction
356
-
357
- function! s:buffer_type(...) dict abort
358
- if self.getvar('fugitive_type') != ''
359
- let type = self.getvar('fugitive_type')
360
- elseif fnamemodify(self.spec(),':p') =~# '.\git/refs/\|\.git/\w*HEAD$'
361
- let type = 'head'
362
- elseif self.getline(1) =~ '^tree \x\{40\}$' && self.getline(2) == ''
363
- let type = 'tree'
364
- elseif self.getline(1) =~ '^\d\{6\} \w\{4\} \x\{40\}\>\t'
365
- let type = 'tree'
366
- elseif self.getline(1) =~ '^\d\{6\} \x\{40\}\> \d\t'
367
- let type = 'index'
368
- elseif isdirectory(self.spec())
369
- let type = 'directory'
370
- elseif self.spec() == ''
371
- let type = 'null'
372
- elseif filereadable(self.spec())
373
- let type = 'file'
374
- else
375
- let type = ''
376
- endif
377
- if a:0
378
- return !empty(filter(copy(a:000),'v:val ==# type'))
379
- else
380
- return type
381
- endif
382
- endfunction
383
-
384
- if has('win32')
385
-
386
- function! s:buffer_spec() dict abort
387
- let bufname = bufname(self['#'])
388
- let retval = ''
389
- for i in split(bufname,'[^:]\zs\\')
390
- let retval = fnamemodify((retval==''?'':retval.'\').i,':.')
391
- endfor
392
- return s:shellslash(fnamemodify(retval,':p'))
393
- endfunction
394
-
395
- else
396
-
397
- function! s:buffer_spec() dict abort
398
- let bufname = bufname(self['#'])
399
- return s:shellslash(bufname == '' ? '' : fnamemodify(bufname,':p'))
400
- endfunction
401
-
402
- endif
403
-
404
- function! s:buffer_name() dict abort
405
- return self.spec()
406
- endfunction
407
-
408
- function! s:buffer_commit() dict abort
409
- return matchstr(self.spec(),'^fugitive://.\{-\}//\zs\w*')
410
- endfunction
411
-
412
- function! s:buffer_path(...) dict abort
413
- let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
414
- if rev != ''
415
- let rev = s:sub(rev,'\w*','')
416
- else
417
- let rev = self.spec()[strlen(self.repo().tree()) : -1]
418
- endif
419
- return s:sub(s:sub(rev,'.\zs/$',''),'^/',a:0 ? a:1 : '')
420
- endfunction
421
-
422
- function! s:buffer_rev() dict abort
423
- let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
424
- if rev =~ '^\x/'
425
- return ':'.rev[0].':'.rev[2:-1]
426
- elseif rev =~ '.'
427
- return s:sub(rev,'/',':')
428
- elseif self.spec() =~ '\.git/index$'
429
- return ':'
430
- elseif self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
431
- return self.spec()[strlen(self.repo().dir())+1 : -1]
432
- else
433
- return self.path()
434
- endif
435
- endfunction
436
-
437
- function! s:buffer_sha1() dict abort
438
- if self.spec() =~ '^fugitive://' || self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
439
- return self.repo().rev_parse(self.rev())
440
- else
441
- return ''
442
- endif
443
- endfunction
444
-
445
- function! s:buffer_expand(rev) dict abort
446
- if a:rev =~# '^:[0-3]$'
447
- let file = a:rev.self.path(':')
448
- elseif a:rev =~# '^[-:]/$'
449
- let file = '/'.self.path()
450
- elseif a:rev =~# '^-'
451
- let file = 'HEAD^{}'.a:rev[1:-1].self.path(':')
452
- elseif a:rev =~# '^@{'
453
- let file = 'HEAD'.a:rev.self.path(':')
454
- elseif a:rev =~# '^[~^]'
455
- let commit = s:sub(self.commit(),'^\d=$','HEAD')
456
- let file = commit.a:rev.self.path(':')
457
- else
458
- let file = a:rev
459
- endif
460
- return s:sub(s:sub(file,'\%$',self.path()),'\.\@<=/$','')
461
- endfunction
462
-
463
- function! s:buffer_containing_commit() dict abort
464
- if self.commit() =~# '^\d$'
465
- return ':'
466
- elseif self.commit() =~# '.'
467
- return self.commit()
468
- else
469
- return 'HEAD'
470
- endif
471
- endfunction
472
-
473
- call s:add_methods('buffer',['getvar','setvar','getline','repo','type','spec','name','commit','path','rev','sha1','expand','containing_commit'])
474
-
475
- " }}}1
476
- " Git {{{1
477
-
478
- call s:command("-bang -nargs=? -complete=customlist,s:GitComplete Git :execute s:Git(<bang>0,<q-args>)")
479
-
480
- function! s:ExecuteInTree(cmd) abort
481
- let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
482
- let dir = getcwd()
483
- try
484
- execute cd.'`=s:repo().tree()`'
485
- execute a:cmd
486
- finally
487
- execute cd.'`=dir`'
488
- endtry
489
- endfunction
490
-
491
- function! s:Git(bang,cmd) abort
492
- let git = s:repo().git_command()
493
- if has('gui_running') && !has('win32')
494
- let git .= ' --no-pager'
495
- endif
496
- let cmd = matchstr(a:cmd,'\v\C.{-}%($|\\@<!%(\\\\)*\|)@=')
497
- call s:ExecuteInTree('!'.git.' '.cmd)
498
- call fugitive#reload_status()
499
- return matchstr(a:cmd,'\v\C\\@<!%(\\\\)*\|\zs.*')
500
- endfunction
501
-
502
- function! s:GitComplete(A,L,P) abort
503
- if !exists('s:exec_path')
504
- let s:exec_path = s:sub(system(g:fugitive_git_executable.' --exec-path'),'\n$','')
505
- endif
506
- let cmds = map(split(glob(s:exec_path.'/git-*'),"\n"),'s:sub(v:val[strlen(s:exec_path)+5 : -1],"\\.exe$","")')
507
- if a:L =~ ' [[:alnum:]-]\+ '
508
- return s:repo().superglob(a:A)
509
- elseif a:A == ''
510
- return cmds
511
- else
512
- return filter(cmds,'v:val[0 : strlen(a:A)-1] ==# a:A')
513
- endif
514
- endfunction
515
-
516
- " }}}1
517
- " Gcd, Glcd {{{1
518
-
519
- function! s:DirComplete(A,L,P) abort
520
- let matches = s:repo().dirglob(a:A)
521
- return matches
522
- endfunction
523
-
524
- 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>)`")
525
- 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>)`")
526
-
527
- " }}}1
528
- " Gstatus {{{1
529
-
530
- call s:command("-bar Gstatus :execute s:Status()")
531
-
532
- function! s:Status() abort
533
- try
534
- Gpedit :
535
- wincmd P
536
- nnoremap <buffer> <silent> q :<C-U>bdelete<CR>
537
- catch /^fugitive:/
538
- return 'echoerr v:errmsg'
539
- endtry
540
- return ''
541
- endfunction
542
-
543
- function! fugitive#reload_status() abort
544
- let mytab = tabpagenr()
545
- for tab in [mytab] + range(1,tabpagenr('$'))
546
- for winnr in range(1,tabpagewinnr(tab,'$'))
547
- if getbufvar(tabpagebuflist(tab)[winnr-1],'fugitive_type') ==# 'index'
548
- execute 'tabnext '.tab
549
- if winnr != winnr()
550
- execute winnr.'wincmd w'
551
- let restorewinnr = 1
552
- endif
553
- try
554
- if !&modified
555
- call s:BufReadIndex()
556
- endif
557
- finally
558
- if exists('restorewinnr')
559
- wincmd p
560
- endif
561
- execute 'tabnext '.mytab
562
- endtry
563
- endif
564
- endfor
565
- endfor
566
- endfunction
567
-
568
- function! s:StageDiff(...) abort
569
- let cmd = a:0 ? a:1 : 'Gdiff'
570
- let section = getline(search('^# .*:$','bnW'))
571
- let line = getline('.')
572
- let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (new commits)\)\=$')
573
- if filename ==# '' && section == '# Changes to be committed:'
574
- return 'Git diff --cached'
575
- elseif filename ==# ''
576
- return 'Git diff'
577
- elseif line =~# '^#\trenamed:' && filename =~ ' -> '
578
- let [old, new] = split(filename,' -> ')
579
- execute 'Gedit '.s:fnameescape(':0:'.new)
580
- return cmd.' HEAD:'.s:fnameescape(old)
581
- elseif section == '# Changes to be committed:'
582
- execute 'Gedit '.s:fnameescape(':0:'.filename)
583
- return cmd.' -'
584
- else
585
- execute 'Gedit '.s:fnameescape('/'.filename)
586
- return cmd
587
- endif
588
- endfunction
589
-
590
- function! s:StageToggle(lnum1,lnum2) abort
591
- try
592
- let output = ''
593
- for lnum in range(a:lnum1,a:lnum2)
594
- let line = getline(lnum)
595
- let repo = s:repo()
596
- if line ==# '# Changes to be committed:'
597
- call repo.git_chomp_in_tree('reset','-q')
598
- silent! edit!
599
- 1
600
- if !search('^# Untracked files:$','W')
601
- call search('^# Change','W')
602
- endif
603
- return ''
604
- elseif line =~# '^# Change\%(d but not updated\|s not staged for commit\):$'
605
- call repo.git_chomp_in_tree('add','-u')
606
- silent! edit!
607
- 1
608
- if !search('^# Untracked files:$','W')
609
- call search('^# Change','W')
610
- endif
611
- return ''
612
- elseif line ==# '# Untracked files:'
613
- " Work around Vim parser idiosyncrasy
614
- call repo.git_chomp_in_tree('add','-N','.')
615
- silent! edit!
616
- 1
617
- if !search('^# Change\%(d but not updated\|s not staged for commit\):$','W')
618
- call search('^# Change','W')
619
- endif
620
- return ''
621
- endif
622
- let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (\a\+ [[:alpha:], ]\+)\)\=$')
623
- if filename ==# ''
624
- continue
625
- endif
626
- if !exists('first_filename')
627
- let first_filename = filename
628
- endif
629
- execute lnum
630
- let section = getline(search('^# .*:$','bnW'))
631
- if line =~# '^#\trenamed:' && filename =~ ' -> '
632
- let cmd = ['mv','--'] + reverse(split(filename,' -> '))
633
- let filename = cmd[-1]
634
- elseif section =~? ' to be '
635
- let cmd = ['reset','-q','--',filename]
636
- elseif line =~# '^#\tdeleted:'
637
- let cmd = ['rm','--',filename]
638
- else
639
- let cmd = ['add','--',filename]
640
- endif
641
- let output .= call(repo.git_chomp_in_tree,cmd,s:repo())."\n"
642
- endfor
643
- if exists('first_filename')
644
- let jump = first_filename
645
- let f = matchstr(getline(a:lnum1-1),'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
646
- if f !=# '' | let jump = f | endif
647
- let f = matchstr(getline(a:lnum2+1),'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
648
- if f !=# '' | let jump = f | endif
649
- silent! edit!
650
- 1
651
- redraw
652
- call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.jump.'\%( (new commits)\)\=\$','W')
653
- endif
654
- echo s:sub(s:gsub(output,'\n+','\n'),'\n$','')
655
- catch /^fugitive:/
656
- return 'echoerr v:errmsg'
657
- endtry
658
- return 'checktime'
659
- endfunction
660
-
661
- function! s:StagePatch(lnum1,lnum2) abort
662
- let add = []
663
- let reset = []
664
-
665
- for lnum in range(a:lnum1,a:lnum2)
666
- let line = getline(lnum)
667
- if line ==# '# Changes to be committed:'
668
- return 'Git reset --patch'
669
- elseif line =~# '^# Change\%(d but not updated\|s not staged for commit\):$'
670
- return 'Git add --patch'
671
- endif
672
- let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (new commits)\)\=$')
673
- if filename ==# ''
674
- continue
675
- endif
676
- if !exists('first_filename')
677
- let first_filename = filename
678
- endif
679
- execute lnum
680
- let section = getline(search('^# .*:$','bnW'))
681
- if line =~# '^#\trenamed:' && filename =~ ' -> '
682
- let reset += [split(filename,' -> ')[1]]
683
- elseif section =~? ' to be '
684
- let reset += [filename]
685
- elseif line !~# '^#\tdeleted:'
686
- let add += [filename]
687
- endif
688
- endfor
689
- try
690
- if !empty(add)
691
- execute "Git add --patch -- ".join(map(add,'s:shellesc(v:val)'))
692
- endif
693
- if !empty(reset)
694
- execute "Git reset --patch -- ".join(map(add,'s:shellesc(v:val)'))
695
- endif
696
- if exists('first_filename')
697
- silent! edit!
698
- 1
699
- redraw
700
- call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.first_filename.'\%( (new commits)\)\=\$','W')
701
- endif
702
- catch /^fugitive:/
703
- return 'echoerr v:errmsg'
704
- endtry
705
- return 'checktime'
706
- endfunction
707
-
708
- " }}}1
709
- " Gcommit {{{1
710
-
711
- call s:command("-nargs=? -complete=customlist,s:CommitComplete Gcommit :execute s:Commit(<q-args>)")
712
-
713
- function! s:Commit(args) abort
714
- let old_type = s:buffer().type()
715
- let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
716
- let dir = getcwd()
717
- let msgfile = s:repo().dir('COMMIT_EDITMSG')
718
- let outfile = tempname()
719
- let errorfile = tempname()
720
- try
721
- execute cd.'`=s:repo().tree()`'
722
- if &shell =~# 'cmd'
723
- let command = ''
724
- let old_editor = $GIT_EDITOR
725
- let $GIT_EDITOR = 'false'
726
- else
727
- let command = 'env GIT_EDITOR=false '
728
- endif
729
- let command .= s:repo().git_command('commit').' '.a:args
730
- if &shell =~# 'csh'
731
- silent execute '!('.command.' > '.outfile.') >& '.errorfile
732
- elseif a:args =~# '\%(^\| \)--interactive\>'
733
- execute '!'.command.' 2> '.errorfile
734
- else
735
- silent execute '!'.command.' > '.outfile.' 2> '.errorfile
736
- endif
737
- if !v:shell_error
738
- if filereadable(outfile)
739
- for line in readfile(outfile)
740
- echo line
741
- endfor
742
- endif
743
- return ''
744
- else
745
- let errors = readfile(errorfile)
746
- let error = get(errors,-2,get(errors,-1,'!'))
747
- if error =~# '\<false''\=\.$'
748
- let args = a:args
749
- let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-[se]|--edit|--interactive)%($| )','')
750
- let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-F|--file|-m|--message)%(\s+|\=)%(''[^'']*''|"%(\\.|[^"])*"|\\.|\S)*','')
751
- let args = s:gsub(args,'%(^| )@<=[%#]%(:\w)*','\=expand(submatch(0))')
752
- let args = '-F '.s:shellesc(msgfile).' '.args
753
- if args !~# '\%(^\| \)--cleanup\>'
754
- let args = '--cleanup=strip '.args
755
- endif
756
- let old_nr = bufnr('')
757
- if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&mod
758
- edit `=msgfile`
759
- else
760
- keepalt split `=msgfile`
761
- endif
762
- if old_type ==# 'index'
763
- execute 'bdelete '.old_nr
764
- endif
765
- let b:fugitive_commit_arguments = args
766
- setlocal bufhidden=delete filetype=gitcommit
767
- return '1'
768
- elseif error ==# '!'
769
- return s:Status()
770
- else
771
- call s:throw(error)
772
- endif
773
- endif
774
- catch /^fugitive:/
775
- return 'echoerr v:errmsg'
776
- finally
777
- if exists('old_editor')
778
- let $GIT_EDITOR = old_editor
779
- endif
780
- call delete(outfile)
781
- call delete(errorfile)
782
- execute cd.'`=dir`'
783
- call fugitive#reload_status()
784
- endtry
785
- endfunction
786
-
787
- function! s:CommitComplete(A,L,P) abort
788
- if a:A =~ '^-' || type(a:A) == type(0) " a:A is 0 on :Gcommit -<Tab>
789
- 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']
790
- return filter(args,'v:val[0 : strlen(a:A)-1] ==# a:A')
791
- else
792
- return s:repo().superglob(a:A)
793
- endif
794
- endfunction
795
-
796
- function! s:FinishCommit()
797
- let args = getbufvar(+expand('<abuf>'),'fugitive_commit_arguments')
798
- if !empty(args)
799
- call setbufvar(+expand('<abuf>'),'fugitive_commit_arguments','')
800
- return s:Commit(args)
801
- endif
802
- return ''
803
- endfunction
804
-
805
- augroup fugitive_commit
806
- autocmd!
807
- autocmd VimLeavePre,BufDelete *.git/COMMIT_EDITMSG execute s:sub(s:FinishCommit(), '^echoerr (.*)', 'echohl ErrorMsg|echo \1|echohl NONE')
808
- augroup END
809
-
810
- " }}}1
811
- " Ggrep, Glog {{{1
812
-
813
- if !exists('g:fugitive_summary_format')
814
- let g:fugitive_summary_format = '%s'
815
- endif
816
-
817
- call s:command("-bang -nargs=? -complete=customlist,s:EditComplete Ggrep :execute s:Grep(<bang>0,<q-args>)")
818
- call s:command("-bar -bang -nargs=* -complete=customlist,s:EditComplete Glog :execute s:Log('grep<bang>',<f-args>)")
819
-
820
- function! s:Grep(bang,arg) abort
821
- let grepprg = &grepprg
822
- let grepformat = &grepformat
823
- let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
824
- let dir = getcwd()
825
- try
826
- execute cd.'`=s:repo().tree()`'
827
- let &grepprg = s:repo().git_command('--no-pager', 'grep', '-n')
828
- let &grepformat = '%f:%l:%m'
829
- exe 'grep! '.escape(matchstr(a:arg,'\v\C.{-}%($|[''" ]\@=\|)@='),'|')
830
- let list = getqflist()
831
- for entry in list
832
- if bufname(entry.bufnr) =~ ':'
833
- let entry.filename = s:repo().translate(bufname(entry.bufnr))
834
- unlet! entry.bufnr
835
- elseif a:arg =~# '\%(^\| \)--cached\>'
836
- let entry.filename = s:repo().translate(':0:'.bufname(entry.bufnr))
837
- unlet! entry.bufnr
838
- endif
839
- endfor
840
- call setqflist(list,'r')
841
- if !a:bang && !empty(list)
842
- return 'cfirst'.matchstr(a:arg,'\v\C[''" ]\zs\|.*')
843
- else
844
- return matchstr(a:arg,'\v\C[''" ]\|\zs.*')
845
- endif
846
- finally
847
- let &grepprg = grepprg
848
- let &grepformat = grepformat
849
- execute cd.'`=dir`'
850
- endtry
851
- endfunction
852
-
853
- function! s:Log(cmd,...)
854
- let path = s:buffer().path('/')
855
- if path =~# '^/\.git\%(/\|$\)' || index(a:000,'--') != -1
856
- let path = ''
857
- endif
858
- let cmd = ['--no-pager', 'log', '--no-color']
859
- let cmd += [escape('--pretty=format:fugitive://'.s:repo().dir().'//%H'.path.'::'.g:fugitive_summary_format,'%')]
860
- if empty(filter(a:000[0 : index(a:000,'--')],'v:val !~# "^-"'))
861
- if s:buffer().commit() =~# '\x\{40\}'
862
- let cmd += [s:buffer().commit()]
863
- elseif s:buffer().path() =~# '^\.git/refs/\|^\.git/.*HEAD$'
864
- let cmd += [s:buffer().path()[5:-1]]
865
- endif
866
- end
867
- let cmd += map(copy(a:000),'s:sub(v:val,"^\\%(%(:\\w)*)","\\=fnamemodify(s:buffer().path(),submatch(1))")')
868
- if path =~# '/.'
869
- let cmd += ['--',path[1:-1]]
870
- endif
871
- let grepformat = &grepformat
872
- let grepprg = &grepprg
873
- let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
874
- let dir = getcwd()
875
- try
876
- execute cd.'`=s:repo().tree()`'
877
- let &grepprg = call(s:repo().git_command,cmd,s:repo())
878
- let &grepformat = '%f::%m'
879
- exe a:cmd
880
- finally
881
- let &grepformat = grepformat
882
- let &grepprg = grepprg
883
- execute cd.'`=dir`'
884
- endtry
885
- endfunction
886
-
887
- " }}}1
888
- " Gedit, Gpedit, Gsplit, Gvsplit, Gtabedit, Gread {{{1
889
-
890
- function! s:Edit(cmd,...) abort
891
- if a:0 && a:1 == ''
892
- return ''
893
- elseif a:0
894
- let file = s:buffer().expand(a:1)
895
- elseif s:buffer().commit() ==# '' && s:buffer().path('/') !~# '^/.git\>'
896
- let file = s:buffer().path(':')
897
- else
898
- let file = s:buffer().path('/')
899
- endif
900
- try
901
- let file = s:repo().translate(file)
902
- catch /^fugitive:/
903
- return 'echoerr v:errmsg'
904
- endtry
905
- if a:cmd ==# 'read'
906
- return 'silent %delete_|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.')
907
- else
908
- if &previewwindow && getbufvar('','fugitive_type') ==# 'index'
909
- wincmd p
910
- endif
911
- return a:cmd.' '.s:fnameescape(file)
912
- endif
913
- endfunction
914
-
915
- function! s:EditComplete(A,L,P) abort
916
- return s:repo().superglob(a:A)
917
- endfunction
918
-
919
- call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Ge :execute s:Edit('edit<bang>',<f-args>)")
920
- call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gedit :execute s:Edit('edit<bang>',<f-args>)")
921
- call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gpedit :execute s:Edit('pedit<bang>',<f-args>)")
922
- call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gsplit :execute s:Edit('split<bang>',<f-args>)")
923
- call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gvsplit :execute s:Edit('vsplit<bang>',<f-args>)")
924
- call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gtabedit :execute s:Edit('tabedit<bang>',<f-args>)")
925
- call s:command("-bar -bang -nargs=? -count -complete=customlist,s:EditComplete Gread :execute s:Edit((!<count> && <line1> ? '' : <count>).'read<bang>',<f-args>)")
926
-
927
- " }}}1
928
- " Gwrite, Gwq {{{1
929
-
930
- call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gwrite :execute s:Write(<bang>0,<f-args>)")
931
- call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gw :execute s:Write(<bang>0,<f-args>)")
932
- call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gwq :execute s:Wq(<bang>0,<f-args>)")
933
-
934
- function! s:Write(force,...) abort
935
- if exists('b:fugitive_commit_arguments')
936
- return 'write|bdelete'
937
- elseif expand('%:t') == 'COMMIT_EDITMSG' && $GIT_INDEX_FILE != ''
938
- return 'wq'
939
- elseif s:buffer().type() == 'index'
940
- return 'Gcommit'
941
- endif
942
- let mytab = tabpagenr()
943
- let mybufnr = bufnr('')
944
- let path = a:0 ? a:1 : s:buffer().path()
945
- if path =~# '^:\d\>'
946
- return 'write'.(a:force ? '! ' : ' ').s:fnameescape(s:repo().translate(s:buffer().expand(path)))
947
- endif
948
- let always_permitted = (s:buffer().path() ==# path && s:buffer().commit() =~# '^0\=$')
949
- 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) !=# ''
950
- let v:errmsg = 'fugitive: file has uncommitted changes (use ! to override)'
951
- return 'echoerr v:errmsg'
952
- endif
953
- let file = s:repo().translate(path)
954
- let treebufnr = 0
955
- for nr in range(1,bufnr('$'))
956
- if fnamemodify(bufname(nr),':p') ==# file
957
- let treebufnr = nr
958
- endif
959
- endfor
960
-
961
- if treebufnr > 0 && treebufnr != bufnr('')
962
- let temp = tempname()
963
- silent execute '%write '.temp
964
- for tab in [mytab] + range(1,tabpagenr('$'))
965
- for winnr in range(1,tabpagewinnr(tab,'$'))
966
- if tabpagebuflist(tab)[winnr-1] == treebufnr
967
- execute 'tabnext '.tab
968
- if winnr != winnr()
969
- execute winnr.'wincmd w'
970
- let restorewinnr = 1
971
- endif
972
- try
973
- let lnum = line('.')
974
- let last = line('$')
975
- silent execute '$read '.temp
976
- silent execute '1,'.last.'delete_'
977
- silent write!
978
- silent execute lnum
979
- let did = 1
980
- finally
981
- if exists('restorewinnr')
982
- wincmd p
983
- endif
984
- execute 'tabnext '.mytab
985
- endtry
986
- endif
987
- endfor
988
- endfor
989
- if !exists('did')
990
- call writefile(readfile(temp,'b'),file,'b')
991
- endif
992
- else
993
- execute 'write! '.s:fnameescape(s:repo().translate(path))
994
- endif
995
-
996
- if a:force
997
- let error = s:repo().git_chomp_in_tree('add', '--force', file)
998
- else
999
- let error = s:repo().git_chomp_in_tree('add', file)
1000
- endif
1001
- if v:shell_error
1002
- let v:errmsg = 'fugitive: '.error
1003
- return 'echoerr v:errmsg'
1004
- endif
1005
- if s:buffer().path() ==# path && s:buffer().commit() =~# '^\d$'
1006
- set nomodified
1007
- endif
1008
-
1009
- let one = s:repo().translate(':1:'.path)
1010
- let two = s:repo().translate(':2:'.path)
1011
- let three = s:repo().translate(':3:'.path)
1012
- for nr in range(1,bufnr('$'))
1013
- if bufloaded(nr) && !getbufvar(nr,'&modified') && (bufname(nr) == one || bufname(nr) == two || bufname(nr) == three)
1014
- execute nr.'bdelete'
1015
- endif
1016
- endfor
1017
-
1018
- unlet! restorewinnr
1019
- let zero = s:repo().translate(':0:'.path)
1020
- for tab in range(1,tabpagenr('$'))
1021
- for winnr in range(1,tabpagewinnr(tab,'$'))
1022
- let bufnr = tabpagebuflist(tab)[winnr-1]
1023
- let bufname = bufname(bufnr)
1024
- if bufname ==# zero && bufnr != mybufnr
1025
- execute 'tabnext '.tab
1026
- if winnr != winnr()
1027
- execute winnr.'wincmd w'
1028
- let restorewinnr = 1
1029
- endif
1030
- try
1031
- let lnum = line('.')
1032
- let last = line('$')
1033
- silent $read `=file`
1034
- silent execute '1,'.last.'delete_'
1035
- silent execute lnum
1036
- set nomodified
1037
- diffupdate
1038
- finally
1039
- if exists('restorewinnr')
1040
- wincmd p
1041
- endif
1042
- execute 'tabnext '.mytab
1043
- endtry
1044
- break
1045
- endif
1046
- endfor
1047
- endfor
1048
- call fugitive#reload_status()
1049
- return 'checktime'
1050
- endfunction
1051
-
1052
- function! s:Wq(force,...) abort
1053
- let bang = a:force ? '!' : ''
1054
- if exists('b:fugitive_commit_arguments')
1055
- return 'wq'.bang
1056
- endif
1057
- let result = call(s:function('s:Write'),[a:force]+a:000)
1058
- if result =~# '^\%(write\|wq\|echoerr\)'
1059
- return s:sub(result,'^write','wq')
1060
- else
1061
- return result.'|quit'.bang
1062
- endif
1063
- endfunction
1064
-
1065
- " }}}1
1066
- " Gdiff {{{1
1067
-
1068
- call s:command("-bang -bar -nargs=? -complete=customlist,s:EditComplete Gdiff :execute s:Diff(<bang>0,<f-args>)")
1069
- call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gvdiff :execute s:Diff(0,<f-args>)")
1070
- call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gsdiff :execute s:Diff(1,<f-args>)")
1071
-
1072
- augroup fugitive_diff
1073
- autocmd!
1074
- autocmd BufWinLeave * if s:diff_window_count() == 2 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | call s:diff_off_all(getbufvar(+expand('<abuf>'), 'git_dir')) | endif
1075
- autocmd BufWinEnter * if s:diff_window_count() == 1 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | diffoff | endif
1076
- augroup END
1077
-
1078
- function! s:diff_window_count()
1079
- let c = 0
1080
- for nr in range(1,winnr('$'))
1081
- let c += getwinvar(nr,'&diff')
1082
- endfor
1083
- return c
1084
- endfunction
1085
-
1086
- function! s:diff_off_all(dir)
1087
- for nr in range(1,winnr('$'))
1088
- if getwinvar(nr,'&diff')
1089
- if nr != winnr()
1090
- execute nr.'wincmd w'
1091
- let restorewinnr = 1
1092
- endif
1093
- if exists('b:git_dir') && b:git_dir ==# a:dir
1094
- diffoff
1095
- endif
1096
- if exists('restorewinnr')
1097
- wincmd p
1098
- endif
1099
- endif
1100
- endfor
1101
- endfunction
1102
-
1103
- function! s:buffer_compare_age(commit) dict abort
1104
- let scores = {':0': 1, ':1': 2, ':2': 3, ':': 4, ':3': 5}
1105
- let my_score = get(scores,':'.self.commit(),0)
1106
- let their_score = get(scores,':'.a:commit,0)
1107
- if my_score || their_score
1108
- return my_score < their_score ? -1 : my_score != their_score
1109
- elseif self.commit() ==# a:commit
1110
- return 0
1111
- endif
1112
- let base = self.repo().git_chomp('merge-base',self.commit(),a:commit)
1113
- if base ==# self.commit()
1114
- return -1
1115
- elseif base ==# a:commit
1116
- return 1
1117
- endif
1118
- let my_time = +self.repo().git_chomp('log','--max-count=1','--pretty=format:%at',self.commit())
1119
- let their_time = +self.repo().git_chomp('log','--max-count=1','--pretty=format:%at',a:commit)
1120
- return my_time < their_time ? -1 : my_time != their_time
1121
- endfunction
1122
-
1123
- call s:add_methods('buffer',['compare_age'])
1124
-
1125
- function! s:Diff(bang,...) abort
1126
- let split = a:bang ? 'split' : 'vsplit'
1127
- if exists(':DiffGitCached')
1128
- return 'DiffGitCached'
1129
- elseif (!a:0 || a:1 == ':') && s:buffer().commit() =~# '^[0-1]\=$' && s:repo().git_chomp_in_tree('ls-files', '--unmerged', '--', s:buffer().path()) !=# ''
1130
- let nr = bufnr('')
1131
- execute 'leftabove '.split.' `=fugitive#buffer().repo().translate(s:buffer().expand('':2''))`'
1132
- execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
1133
- diffthis
1134
- wincmd p
1135
- execute 'rightbelow '.split.' `=fugitive#buffer().repo().translate(s:buffer().expand('':3''))`'
1136
- execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
1137
- diffthis
1138
- wincmd p
1139
- diffthis
1140
- return ''
1141
- elseif a:0
1142
- if a:1 ==# ''
1143
- return ''
1144
- elseif a:1 ==# '/'
1145
- let file = s:buffer().path('/')
1146
- elseif a:1 ==# ':'
1147
- let file = s:buffer().path(':0:')
1148
- elseif a:1 =~# '^:/.'
1149
- try
1150
- let file = s:repo().rev_parse(a:1).s:buffer().path(':')
1151
- catch /^fugitive:/
1152
- return 'echoerr v:errmsg'
1153
- endtry
1154
- else
1155
- let file = s:buffer().expand(a:1)
1156
- endif
1157
- if file !~# ':' && file !~# '^/' && s:repo().git_chomp('cat-file','-t',file) =~# '^\%(tag\|commit\)$'
1158
- let file = file.s:buffer().path(':')
1159
- endif
1160
- else
1161
- let file = s:buffer().path(s:buffer().commit() == '' ? ':0:' : '/')
1162
- endif
1163
- try
1164
- let spec = s:repo().translate(file)
1165
- let commit = matchstr(spec,'\C[^:/]//\zs\x\+')
1166
- if s:buffer().compare_age(commit) < 0
1167
- execute 'rightbelow '.split.' `=spec`'
1168
- else
1169
- execute 'leftabove '.split.' `=spec`'
1170
- endif
1171
- diffthis
1172
- wincmd p
1173
- diffthis
1174
- return ''
1175
- catch /^fugitive:/
1176
- return 'echoerr v:errmsg'
1177
- endtry
1178
- endfunction
1179
-
1180
- " }}}1
1181
- " Gmove, Gremove {{{1
1182
-
1183
- function! s:Move(force,destination)
1184
- if a:destination =~# '^/'
1185
- let destination = a:destination[1:-1]
1186
- else
1187
- let destination = fnamemodify(s:sub(a:destination,'[%#]%(:\w)*','\=expand(submatch(0))'),':p')
1188
- if destination[0:strlen(s:repo().tree())] ==# s:repo().tree('')
1189
- let destination = destination[strlen(s:repo().tree('')):-1]
1190
- endif
1191
- endif
1192
- if isdirectory(s:buffer().name())
1193
- " Work around Vim parser idiosyncrasy
1194
- let discarded = s:buffer().setvar('&swapfile',0)
1195
- endif
1196
- let message = call(s:repo().git_chomp_in_tree,['mv']+(a:force ? ['-f'] : [])+['--', s:buffer().path(), destination], s:repo())
1197
- if v:shell_error
1198
- let v:errmsg = 'fugitive: '.message
1199
- return 'echoerr v:errmsg'
1200
- endif
1201
- let destination = s:repo().tree(destination)
1202
- if isdirectory(destination)
1203
- let destination = fnamemodify(s:sub(destination,'/$','').'/'.expand('%:t'),':.')
1204
- endif
1205
- call fugitive#reload_status()
1206
- if s:buffer().commit() == ''
1207
- if isdirectory(destination)
1208
- return 'edit '.s:fnameescape(destination)
1209
- else
1210
- return 'saveas! '.s:fnameescape(destination)
1211
- endif
1212
- else
1213
- return 'file '.s:fnameescape(s:repo().translate(':0:'.destination)
1214
- endif
1215
- endfunction
1216
-
1217
- function! s:MoveComplete(A,L,P)
1218
- if a:A =~ '^/'
1219
- return s:repo().superglob(a:A)
1220
- else
1221
- let matches = split(glob(a:A.'*'),"\n")
1222
- call map(matches,'v:val !~ "/$" && isdirectory(v:val) ? v:val."/" : v:val')
1223
- return matches
1224
- endif
1225
- endfunction
1226
-
1227
- function! s:Remove(force)
1228
- if s:buffer().commit() ==# ''
1229
- let cmd = ['rm']
1230
- elseif s:buffer().commit() ==# '0'
1231
- let cmd = ['rm','--cached']
1232
- else
1233
- let v:errmsg = 'fugitive: rm not supported here'
1234
- return 'echoerr v:errmsg'
1235
- endif
1236
- if a:force
1237
- let cmd += ['--force']
1238
- endif
1239
- let message = call(s:repo().git_chomp_in_tree,cmd+['--',s:buffer().path()],s:repo())
1240
- if v:shell_error
1241
- let v:errmsg = 'fugitive: '.s:sub(message,'error:.*\zs\n\(.*-f.*',' (add ! to force)')
1242
- return 'echoerr '.string(v:errmsg)
1243
- else
1244
- call fugitive#reload_status()
1245
- return 'bdelete'.(a:force ? '!' : '')
1246
- endif
1247
- endfunction
1248
-
1249
- augroup fugitive_remove
1250
- autocmd!
1251
- autocmd User Fugitive if s:buffer().commit() =~# '^0\=$' |
1252
- \ exe "command! -buffer -bar -bang -nargs=1 -complete=customlist,s:MoveComplete Gmove :execute s:Move(<bang>0,<q-args>)" |
1253
- \ exe "command! -buffer -bar -bang Gremove :execute s:Remove(<bang>0)" |
1254
- \ endif
1255
- augroup END
1256
-
1257
- " }}}1
1258
- " Gblame {{{1
1259
-
1260
- augroup fugitive_blame
1261
- autocmd!
1262
- autocmd BufReadPost *.fugitiveblame setfiletype fugitiveblame
1263
- autocmd FileType fugitiveblame setlocal nomodeline | if exists('b:git_dir') | let &l:keywordprg = s:repo().keywordprg() | endif
1264
- autocmd Syntax fugitiveblame call s:BlameSyntax()
1265
- 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
1266
- augroup END
1267
-
1268
- function! s:Blame(bang,line1,line2,count,args) abort
1269
- try
1270
- if s:buffer().path() == ''
1271
- call s:throw('file or blob required')
1272
- endif
1273
- if filter(copy(a:args),'v:val !~# "^\\%(--root\|--show-name\\|-\\=\\%([ltwfs]\\|[MC]\\d*\\)\\+\\)$"') != []
1274
- call s:throw('unsupported option')
1275
- endif
1276
- call map(a:args,'s:sub(v:val,"^\\ze[^-]","-")')
1277
- let git_dir = s:repo().dir()
1278
- let cmd = ['--no-pager', 'blame', '--show-number'] + a:args
1279
- if s:buffer().commit() =~# '\D\|..'
1280
- let cmd += [s:buffer().commit()]
1281
- else
1282
- let cmd += ['--contents', '-']
1283
- endif
1284
- let basecmd = call(s:repo().git_command,cmd+['--',s:buffer().path()],s:repo())
1285
- try
1286
- let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
1287
- if !s:repo().bare()
1288
- let dir = getcwd()
1289
- execute cd.'`=s:repo().tree()`'
1290
- endif
1291
- if a:count
1292
- execute 'write !'.substitute(basecmd,' blame ',' blame -L '.a:line1.','.a:line2.' ','g')
1293
- else
1294
- let error = tempname()
1295
- let temp = error.'.fugitiveblame'
1296
- if &shell =~# 'csh'
1297
- silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
1298
- else
1299
- silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
1300
- endif
1301
- if exists('l:dir')
1302
- execute cd.'`=dir`'
1303
- unlet dir
1304
- endif
1305
- if v:shell_error
1306
- call s:throw(join(readfile(error),"\n"))
1307
- endif
1308
- let bufnr = bufnr('')
1309
- let restore = 'call setwinvar(bufwinnr('.bufnr.'),"&scrollbind",0)'
1310
- if &l:wrap
1311
- let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&wrap",1)'
1312
- endif
1313
- if &l:foldenable
1314
- let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&foldenable",1)'
1315
- endif
1316
- let winnr = winnr()
1317
- windo set noscrollbind
1318
- exe winnr.'wincmd w'
1319
- setlocal scrollbind nowrap nofoldenable
1320
- let top = line('w0') + &scrolloff
1321
- let current = line('.')
1322
- exe 'leftabove vsplit '.temp
1323
- let b:git_dir = git_dir
1324
- let b:fugitive_type = 'blame'
1325
- let b:fugitive_blamed_bufnr = bufnr
1326
- let w:fugitive_restore = restore
1327
- let b:fugitive_blame_arguments = join(a:args,' ')
1328
- call s:Detect(expand('%:p'))
1329
- execute top
1330
- normal! zt
1331
- execute current
1332
- execute "vertical resize ".(match(getline('.'),'\s\+\d\+)')+1)
1333
- setlocal nomodified nomodifiable bufhidden=delete nonumber scrollbind nowrap foldcolumn=0 nofoldenable filetype=fugitiveblame
1334
- nnoremap <buffer> <silent> q :<C-U>bdelete<CR>
1335
- nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>BlameJump('')<CR>
1336
- nnoremap <buffer> <silent> P :<C-U>exe <SID>BlameJump('^'.v:count1)<CR>
1337
- nnoremap <buffer> <silent> ~ :<C-U>exe <SID>BlameJump('~'.v:count1)<CR>
1338
- nnoremap <buffer> <silent> o :<C-U>exe <SID>Edit((&splitbelow ? "botright" : "topleft")." split", matchstr(getline('.'),'\x\+'))<CR>
1339
- nnoremap <buffer> <silent> O :<C-U>exe <SID>Edit("tabedit", matchstr(getline('.'),'\x\+'))<CR>
1340
- syncbind
1341
- endif
1342
- finally
1343
- if exists('l:dir')
1344
- execute cd.'`=dir`'
1345
- endif
1346
- endtry
1347
- return ''
1348
- catch /^fugitive:/
1349
- return 'echoerr v:errmsg'
1350
- endtry
1351
- endfunction
1352
-
1353
- function! s:BlameJump(suffix) abort
1354
- let commit = matchstr(getline('.'),'^\^\=\zs\x\+')
1355
- if commit =~# '^0\+$'
1356
- let commit = ':0'
1357
- endif
1358
- let lnum = matchstr(getline('.'),'\d\+\ze\s\+[([:digit:]]')
1359
- let path = matchstr(getline('.'),'^\^\=\zs\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
1360
- if path ==# ''
1361
- let path = s:buffer(b:fugitive_blamed_bufnr).path()
1362
- endif
1363
- let args = b:fugitive_blame_arguments
1364
- let offset = line('.') - line('w0')
1365
- let bufnr = bufnr('%')
1366
- let winnr = bufwinnr(b:fugitive_blamed_bufnr)
1367
- if winnr > 0
1368
- exe winnr.'wincmd w'
1369
- endif
1370
- execute s:Edit('edit',commit.a:suffix.':'.path)
1371
- if winnr > 0
1372
- exe bufnr.'bdelete'
1373
- endif
1374
- execute 'Gblame '.args
1375
- execute lnum
1376
- let delta = line('.') - line('w0') - offset
1377
- if delta > 0
1378
- execute 'norm! 'delta."\<C-E>"
1379
- elseif delta < 0
1380
- execute 'norm! '(-delta)."\<C-Y>"
1381
- endif
1382
- syncbind
1383
- return ''
1384
- endfunction
1385
-
1386
- function! s:BlameSyntax() abort
1387
- let b:current_syntax = 'fugitiveblame'
1388
- syn match FugitiveblameBoundary "^\^"
1389
- syn match FugitiveblameBlank "^\s\+\s\@=" nextgroup=FugitiveblameAnnotation,fugitiveblameOriginalFile,FugitiveblameOriginalLineNumber skipwhite
1390
- syn match FugitiveblameHash "\%(^\^\=\)\@<=\x\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
1391
- syn match FugitiveblameUncommitted "\%(^\^\=\)\@<=0\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
1392
- syn region FugitiveblameAnnotation matchgroup=FugitiveblameDelimiter start="(" end="\%( \d\+\)\@<=)" contained keepend oneline
1393
- syn match FugitiveblameTime "[0-9:/+-][0-9:/+ -]*[0-9:/+-]\%( \+\d\+)\)\@=" contained containedin=FugitiveblameAnnotation
1394
- syn match FugitiveblameLineNumber " \@<=\d\+)\@=" contained containedin=FugitiveblameAnnotation
1395
- syn match FugitiveblameOriginalFile " \%(\f\+\D\@<=\|\D\@=\f\+\)\%(\%(\s\+\d\+\)\=\s\%((\|\s*\d\+)\)\)\@=" contained nextgroup=FugitiveblameOriginalLineNumber,FugitiveblameAnnotation skipwhite
1396
- syn match FugitiveblameOriginalLineNumber " \@<=\d\+\%(\s(\)\@=" contained nextgroup=FugitiveblameAnnotation skipwhite
1397
- syn match FugitiveblameOriginalLineNumber " \@<=\d\+\%(\s\+\d\+)\)\@=" contained nextgroup=FugitiveblameShort skipwhite
1398
- syn match FugitiveblameShort "\d\+)" contained contains=FugitiveblameLineNumber
1399
- syn match FugitiveblameNotCommittedYet "(\@<=Not Committed Yet\>" contained containedin=FugitiveblameAnnotation
1400
- hi def link FugitiveblameBoundary Keyword
1401
- hi def link FugitiveblameHash Identifier
1402
- hi def link FugitiveblameUncommitted Function
1403
- hi def link FugitiveblameTime PreProc
1404
- hi def link FugitiveblameLineNumber Number
1405
- hi def link FugitiveblameOriginalFile String
1406
- hi def link FugitiveblameOriginalLineNumber Float
1407
- hi def link FugitiveblameShort FugitiveblameDelimiter
1408
- hi def link FugitiveblameDelimiter Delimiter
1409
- hi def link FugitiveblameNotCommittedYet Comment
1410
- endfunction
1411
-
1412
- " }}}1
1413
- " Gbrowse {{{1
1414
-
1415
- call s:command("-bar -bang -count=0 -nargs=? -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(<bang>0,<line1>,<count>,<f-args>)")
1416
-
1417
- function! s:Browse(bang,line1,count,...) abort
1418
- try
1419
- let rev = a:0 ? substitute(a:1,'@[[:alnum:]_-]*\%(://.\{-\}\)\=$','','') : ''
1420
- if rev ==# ''
1421
- let expanded = s:buffer().rev()
1422
- elseif rev ==# ':'
1423
- let expanded = s:buffer().path('/')
1424
- else
1425
- let expanded = s:buffer().expand(rev)
1426
- endif
1427
- let full = s:repo().translate(expanded)
1428
- let commit = ''
1429
- if full =~# '^fugitive://'
1430
- let commit = matchstr(full,'://.*//\zs\w\+')
1431
- let path = matchstr(full,'://.*//\w\+\zs/.*')
1432
- if commit =~ '..'
1433
- let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':'))
1434
- else
1435
- let type = 'blob'
1436
- endif
1437
- let path = path[1:-1]
1438
- elseif s:repo().bare()
1439
- let path = '.git/' . full[strlen(s:repo().dir())+1:-1]
1440
- let type = ''
1441
- else
1442
- let path = full[strlen(s:repo().tree())+1:-1]
1443
- if path =~# '^\.git/'
1444
- let type = ''
1445
- elseif isdirectory(full)
1446
- let type = 'tree'
1447
- else
1448
- let type = 'blob'
1449
- endif
1450
- endif
1451
- if path =~# '^\.git/.*HEAD' && filereadable(s:repo().dir(path[5:-1]))
1452
- let body = readfile(s:repo().dir(path[5:-1]))[0]
1453
- if body =~# '^\x\{40\}$'
1454
- let commit = body
1455
- let type = 'commit'
1456
- let path = ''
1457
- elseif body =~# '^ref: refs/'
1458
- let path = '.git/' . matchstr(body,'ref: \zs.*')
1459
- endif
1460
- endif
1461
-
1462
- if a:0 && a:1 =~# '@[[:alnum:]_-]*\%(://.\{-\}\)\=$'
1463
- let remote = matchstr(a:1,'@\zs[[:alnum:]_-]\+\%(://.\{-\}\)\=$')
1464
- elseif path =~# '^\.git/refs/remotes/.'
1465
- let remote = matchstr(path,'^\.git/refs/remotes/\zs[^/]\+')
1466
- else
1467
- let remote = 'origin'
1468
- let branch = matchstr(rev,'^[[:alnum:]/._-]\+\ze[:^~@]')
1469
- if branch ==# '' && path =~# '^\.git/refs/\w\+/'
1470
- let branch = s:sub(path,'^\.git/refs/\w+/','')
1471
- endif
1472
- if filereadable(s:repo().dir('refs/remotes/'.branch))
1473
- let remote = matchstr(branch,'[^/]\+')
1474
- let rev = rev[strlen(remote)+1:-1]
1475
- else
1476
- if branch ==# ''
1477
- let branch = matchstr(s:repo().head_ref(),'\<refs/heads/\zs.*')
1478
- endif
1479
- if branch != ''
1480
- let remote = s:repo().git_chomp('config','branch.'.branch.'.remote')
1481
- if remote ==# ''
1482
- let remote = 'origin'
1483
- elseif rev[0:strlen(branch)-1] ==# branch && rev[strlen(branch)] =~# '[:^~@]'
1484
- let rev = s:repo().git_chomp('config','branch.'.branch.'.merge')[11:-1] . rev[strlen(branch):-1]
1485
- endif
1486
- endif
1487
- endif
1488
- endif
1489
-
1490
- let raw = s:repo().git_chomp('config','remote.'.remote.'.url')
1491
- if raw ==# ''
1492
- let raw = remote
1493
- endif
1494
-
1495
- let url = s:github_url(s:repo(),raw,rev,commit,path,type,a:line1,a:count)
1496
- if url == ''
1497
- let url = s:instaweb_url(s:repo(),rev,commit,path,type,a:count ? a:line1 : 0)
1498
- endif
1499
-
1500
- if url == ''
1501
- call s:throw("Instaweb failed to start and '".remote."' is not a GitHub remote")
1502
- endif
1503
-
1504
- if a:bang
1505
- let @* = url
1506
- return 'echomsg '.string(url)
1507
- else
1508
- return 'echomsg '.string(url).'|silent Git web--browse '.shellescape(url,1)
1509
- endif
1510
- catch /^fugitive:/
1511
- return 'echoerr v:errmsg'
1512
- endtry
1513
- endfunction
1514
-
1515
- function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort
1516
- let path = a:path
1517
- let repo_path = matchstr(a:url,'^\%(https\=://\|git://\|git@\)github\.com[/:]\zs.\{-\}\ze\%(\.git\)\=$')
1518
- if repo_path ==# ''
1519
- return ''
1520
- endif
1521
- let root = 'https://github.com/' . repo_path
1522
- if path =~# '^\.git/refs/heads/'
1523
- let branch = a:repo.git_chomp('config','branch.'.path[16:-1].'.merge')[11:-1]
1524
- if branch ==# ''
1525
- return root . '/commits/' . path[16:-1]
1526
- else
1527
- return root . '/commits/' . branch
1528
- endif
1529
- elseif path =~# '^\.git/refs/.'
1530
- return root . '/commits/' . matchstr(path,'[^/]\+$')
1531
- elseif path =~# '.git/\%(config$\|hooks\>\)'
1532
- return root . '/admin'
1533
- elseif path =~# '^\.git\>'
1534
- return root
1535
- endif
1536
- if a:rev =~# '^[[:alnum:]._-]\+:'
1537
- let commit = matchstr(a:rev,'^[^:]*')
1538
- elseif a:commit =~# '^\d\=$'
1539
- let local = matchstr(a:repo.head_ref(),'\<refs/heads/\zs.*')
1540
- let commit = a:repo.git_chomp('config','branch.'.local.'.merge')[11:-1]
1541
- if commit ==# ''
1542
- let commit = local
1543
- endif
1544
- else
1545
- let commit = a:commit
1546
- endif
1547
- if a:type == 'tree'
1548
- let url = s:sub(root . '/tree/' . commit . '/' . path,'/$','')
1549
- elseif a:type == 'blob'
1550
- let url = root . '/blob/' . commit . '/' . path
1551
- if a:line2 && a:line1 == a:line2
1552
- let url .= '#L' . a:line1
1553
- elseif a:line2
1554
- let url .= '#L' . a:line1 . '-' . a:line2
1555
- endif
1556
- elseif a:type == 'tag'
1557
- let commit = matchstr(getline(3),'^tag \zs.*')
1558
- let url = root . '/tree/' . commit
1559
- else
1560
- let url = root . '/commit/' . commit
1561
- endif
1562
- return url
1563
- endfunction
1564
-
1565
- function! s:instaweb_url(repo,rev,commit,path,type,...) abort
1566
- let output = a:repo.git_chomp('instaweb','-b','unknown')
1567
- if output =~# 'http://'
1568
- let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:repo.dir(),':t')
1569
- else
1570
- return ''
1571
- endif
1572
- if a:path =~# '^\.git/refs/.'
1573
- return root . ';a=shortlog;h=' . matchstr(a:path,'^\.git/\zs.*')
1574
- elseif a:path =~# '^\.git\>'
1575
- return root
1576
- endif
1577
- let url = root
1578
- if a:commit =~# '^\x\{40\}$'
1579
- if a:type ==# 'commit'
1580
- let url .= ';a=commit'
1581
- endif
1582
- let url .= ';h=' . a:repo.rev_parse(a:commit . (a:path == '' ? '' : ':' . a:path))
1583
- else
1584
- if a:type ==# 'blob'
1585
- let tmp = tempname()
1586
- silent execute 'write !'.a:repo.git_command('hash-object','-w','--stdin').' > '.tmp
1587
- let url .= ';h=' . readfile(tmp)[0]
1588
- else
1589
- try
1590
- let url .= ';h=' . a:repo.rev_parse((a:commit == '' ? 'HEAD' : ':' . a:commit) . ':' . a:path)
1591
- catch /^fugitive:/
1592
- call s:throw('fugitive: cannot browse uncommitted file')
1593
- endtry
1594
- endif
1595
- let root .= ';hb=' . matchstr(a:repo.head_ref(),'[^ ]\+$')
1596
- endif
1597
- if a:path !=# ''
1598
- let url .= ';f=' . a:path
1599
- endif
1600
- if a:0 && a:1
1601
- let url .= '#l' . a:1
1602
- endif
1603
- return url
1604
- endfunction
1605
-
1606
- " }}}1
1607
- " File access {{{1
1608
-
1609
- function! s:ReplaceCmd(cmd,...) abort
1610
- let fn = bufname('')
1611
- let tmp = tempname()
1612
- let aw = &autowrite
1613
- let prefix = ''
1614
- try
1615
- if a:0 && a:1 != ''
1616
- if &shell =~# 'cmd'
1617
- let old_index = $GIT_INDEX_FILE
1618
- let $GIT_INDEX_FILE = a:1
1619
- else
1620
- let prefix = 'env GIT_INDEX_FILE='.s:shellesc(a:1).' '
1621
- endif
1622
- endif
1623
- set noautowrite
1624
- silent exe '!'.escape(prefix.a:cmd,'%#').' > '.tmp
1625
- finally
1626
- let &autowrite = aw
1627
- if exists('old_index')
1628
- let $GIT_INDEX_FILE = old_index
1629
- endif
1630
- endtry
1631
- silent exe 'keepalt file '.tmp
1632
- silent edit!
1633
- silent exe 'keepalt file '.s:fnameescape(fn)
1634
- call delete(tmp)
1635
- silent exe 'doau BufReadPost '.s:fnameescape(fn)
1636
- endfunction
1637
-
1638
- function! s:BufReadIndex()
1639
- if !exists('b:fugitive_display_format')
1640
- let b:fugitive_display_format = filereadable(expand('%').'.lock')
1641
- endif
1642
- let b:fugitive_display_format = b:fugitive_display_format % 2
1643
- let b:fugitive_type = 'index'
1644
- try
1645
- let b:git_dir = s:repo().dir()
1646
- setlocal noro ma
1647
- if fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : b:git_dir . '/index', ':p') ==# expand('%:p')
1648
- let index = ''
1649
- else
1650
- let index = expand('%:p')
1651
- endif
1652
- if b:fugitive_display_format
1653
- call s:ReplaceCmd(s:repo().git_command('ls-files','--stage'),index)
1654
- set ft=git nospell
1655
- else
1656
- let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
1657
- let dir = getcwd()
1658
- try
1659
- execute cd.'`=s:repo().tree()`'
1660
- call s:ReplaceCmd(s:repo().git_command('status'),index)
1661
- finally
1662
- execute cd.'`=dir`'
1663
- endtry
1664
- set ft=gitcommit
1665
- endif
1666
- setlocal ro noma nomod nomodeline bufhidden=delete
1667
- nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += 1<Bar>exe <SID>BufReadIndex()<CR>
1668
- nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= 1<Bar>exe <SID>BufReadIndex()<CR>
1669
- nnoremap <buffer> <silent> D :<C-U>execute <SID>StageDiff()<CR>
1670
- nnoremap <buffer> <silent> dd :<C-U>execute <SID>StageDiff()<CR>
1671
- nnoremap <buffer> <silent> dh :<C-U>execute <SID>StageDiff('Gsdiff')<CR>
1672
- nnoremap <buffer> <silent> ds :<C-U>execute <SID>StageDiff('Gsdiff')<CR>
1673
- nnoremap <buffer> <silent> dv :<C-U>execute <SID>StageDiff()<CR>
1674
- nnoremap <buffer> <silent> - :<C-U>execute <SID>StageToggle(line('.'),line('.')+v:count1-1)<CR>
1675
- xnoremap <buffer> <silent> - :<C-U>execute <SID>StageToggle(line("'<"),line("'>"))<CR>
1676
- nnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR>
1677
- xnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line("'<"),line("'>"))<CR>
1678
- nnoremap <buffer> <silent> <C-N> :call search('^#\t.*','W')<Bar>.<CR>
1679
- nnoremap <buffer> <silent> <C-P> :call search('^#\t.*','Wbe')<Bar>.<CR>
1680
- call s:JumpInit()
1681
- nunmap <buffer> P
1682
- nunmap <buffer> ~
1683
- nnoremap <buffer> <silent> C :<C-U>Gcommit<CR>
1684
- catch /^fugitive:/
1685
- return 'echoerr v:errmsg'
1686
- endtry
1687
- endfunction
1688
-
1689
- function! s:FileRead()
1690
- try
1691
- let repo = s:repo(s:ExtractGitDir(expand('<amatch>')))
1692
- let path = s:sub(s:sub(matchstr(expand('<amatch>'),'fugitive://.\{-\}//\zs.*'),'/',':'),'^\d:',':&')
1693
- let hash = repo.rev_parse(path)
1694
- if path =~ '^:'
1695
- let type = 'blob'
1696
- else
1697
- let type = repo.git_chomp('cat-file','-t',hash)
1698
- endif
1699
- " TODO: use count, if possible
1700
- return "read !".escape(repo.git_command('cat-file',type,hash),'%#\')
1701
- catch /^fugitive:/
1702
- return 'echoerr v:errmsg'
1703
- endtry
1704
- endfunction
1705
-
1706
- function! s:BufReadIndexFile()
1707
- try
1708
- let b:fugitive_type = 'blob'
1709
- let b:git_dir = s:repo().dir()
1710
- call s:ReplaceCmd(s:repo().git_command('cat-file','blob',s:buffer().sha1()))
1711
- return ''
1712
- catch /^fugitive: rev-parse/
1713
- silent exe 'doau BufNewFile '.s:fnameescape(bufname(''))
1714
- return ''
1715
- catch /^fugitive:/
1716
- return 'echoerr v:errmsg'
1717
- endtry
1718
- endfunction
1719
-
1720
- function! s:BufWriteIndexFile()
1721
- let tmp = tempname()
1722
- try
1723
- let path = matchstr(expand('<amatch>'),'//\d/\zs.*')
1724
- let stage = matchstr(expand('<amatch>'),'//\zs\d')
1725
- silent execute 'write !'.s:repo().git_command('hash-object','-w','--stdin').' > '.tmp
1726
- let sha1 = readfile(tmp)[0]
1727
- let old_mode = matchstr(s:repo().git_chomp('ls-files','--stage',path),'^\d\+')
1728
- if old_mode == ''
1729
- let old_mode = executable(s:repo().tree(path)) ? '100755' : '100644'
1730
- endif
1731
- let info = old_mode.' '.sha1.' '.stage."\t".path
1732
- call writefile([info],tmp)
1733
- if has('win32')
1734
- let error = system('type '.tmp.'|'.s:repo().git_command('update-index','--index-info'))
1735
- else
1736
- let error = system(s:repo().git_command('update-index','--index-info').' < '.tmp)
1737
- endif
1738
- if v:shell_error == 0
1739
- setlocal nomodified
1740
- silent execute 'doautocmd BufWritePost '.s:fnameescape(expand('%:p'))
1741
- call fugitive#reload_status()
1742
- return ''
1743
- else
1744
- return 'echoerr '.string('fugitive: '.error)
1745
- endif
1746
- finally
1747
- call delete(tmp)
1748
- endtry
1749
- endfunction
1750
-
1751
- function! s:BufReadObject()
1752
- try
1753
- setlocal noro ma
1754
- let b:git_dir = s:repo().dir()
1755
- let hash = s:buffer().sha1()
1756
- if !exists("b:fugitive_type")
1757
- let b:fugitive_type = s:repo().git_chomp('cat-file','-t',hash)
1758
- endif
1759
- if b:fugitive_type !~# '^\%(tag\|commit\|tree\|blob\)$'
1760
- return "echoerr 'fugitive: unrecognized git type'"
1761
- endif
1762
- let firstline = getline('.')
1763
- if !exists('b:fugitive_display_format') && b:fugitive_type != 'blob'
1764
- let b:fugitive_display_format = +getbufvar('#','fugitive_display_format')
1765
- endif
1766
-
1767
- let pos = getpos('.')
1768
- silent %delete
1769
- setlocal endofline
1770
-
1771
- if b:fugitive_type == 'tree'
1772
- let b:fugitive_display_format = b:fugitive_display_format % 2
1773
- if b:fugitive_display_format
1774
- call s:ReplaceCmd(s:repo().git_command('ls-tree',hash))
1775
- else
1776
- call s:ReplaceCmd(s:repo().git_command('show',hash))
1777
- endif
1778
- elseif b:fugitive_type == 'tag'
1779
- let b:fugitive_display_format = b:fugitive_display_format % 2
1780
- if b:fugitive_display_format
1781
- call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
1782
- else
1783
- call s:ReplaceCmd(s:repo().git_command('cat-file','-p',hash))
1784
- endif
1785
- elseif b:fugitive_type == 'commit'
1786
- let b:fugitive_display_format = b:fugitive_display_format % 2
1787
- if b:fugitive_display_format
1788
- call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
1789
- else
1790
- 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))
1791
- call search('^parent ')
1792
- if getline('.') ==# 'parent '
1793
- silent delete_
1794
- else
1795
- silent s/\%(^parent\)\@<! /\rparent /ge
1796
- endif
1797
- if search('^encoding \%(<unknown>\)\=$','W',line('.')+3)
1798
- silent delete_
1799
- end
1800
- 1
1801
- endif
1802
- elseif b:fugitive_type ==# 'blob'
1803
- call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
1804
- endif
1805
- call setpos('.',pos)
1806
- setlocal ro noma nomod nomodeline
1807
- if b:fugitive_type !=# 'blob'
1808
- set filetype=git
1809
- nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += v:count1<Bar>exe <SID>BufReadObject()<CR>
1810
- nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= v:count1<Bar>exe <SID>BufReadObject()<CR>
1811
- else
1812
- call s:JumpInit()
1813
- endif
1814
-
1815
- return ''
1816
- catch /^fugitive:/
1817
- return 'echoerr v:errmsg'
1818
- endtry
1819
- endfunction
1820
-
1821
- augroup fugitive_files
1822
- autocmd!
1823
- autocmd BufReadCmd *.git/index exe s:BufReadIndex()
1824
- autocmd BufReadCmd *.git/*index*.lock exe s:BufReadIndex()
1825
- autocmd FileReadCmd fugitive://**//[0-3]/** exe s:FileRead()
1826
- autocmd BufReadCmd fugitive://**//[0-3]/** exe s:BufReadIndexFile()
1827
- autocmd BufWriteCmd fugitive://**//[0-3]/** exe s:BufWriteIndexFile()
1828
- autocmd BufReadCmd fugitive://**//[0-9a-f][0-9a-f]* exe s:BufReadObject()
1829
- autocmd FileReadCmd fugitive://**//[0-9a-f][0-9a-f]* exe s:FileRead()
1830
- autocmd FileType git call s:JumpInit()
1831
- augroup END
1832
-
1833
- " }}}1
1834
- " Go to file {{{1
1835
-
1836
- function! s:JumpInit() abort
1837
- nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>GF("edit")<CR>
1838
- if !&modifiable
1839
- nnoremap <buffer> <silent> o :<C-U>exe <SID>GF("split")<CR>
1840
- nnoremap <buffer> <silent> O :<C-U>exe <SID>GF("tabedit")<CR>
1841
- nnoremap <buffer> <silent> P :<C-U>exe <SID>Edit('edit',<SID>buffer().commit().'^'.v:count1.<SID>buffer().path(':'))<CR>
1842
- nnoremap <buffer> <silent> ~ :<C-U>exe <SID>Edit('edit',<SID>buffer().commit().'~'.v:count1.<SID>buffer().path(':'))<CR>
1843
- nnoremap <buffer> <silent> C :<C-U>exe <SID>Edit('edit',<SID>buffer().containing_commit())<CR>
1844
- nnoremap <buffer> <silent> cc :<C-U>exe <SID>Edit('edit',<SID>buffer().containing_commit())<CR>
1845
- nnoremap <buffer> <silent> co :<C-U>exe <SID>Edit('split',<SID>buffer().containing_commit())<CR>
1846
- nnoremap <buffer> <silent> cO :<C-U>exe <SID>Edit('tabedit',<SID>buffer().containing_commit())<CR>
1847
- nnoremap <buffer> <silent> cp :<C-U>exe <SID>Edit('pedit',<SID>buffer().containing_commit())<CR>
1848
- endif
1849
- endfunction
1850
-
1851
- function! s:GF(mode) abort
1852
- try
1853
- let buffer = s:buffer()
1854
- let myhash = buffer.sha1()
1855
-
1856
- if buffer.type('tree')
1857
- let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
1858
- if showtree && line('.') == 1
1859
- return ""
1860
- elseif showtree && line('.') > 2
1861
- return s:Edit(a:mode,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(getline('.'),'/$',''))
1862
- elseif getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
1863
- return s:Edit(a:mode,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$',''))
1864
- endif
1865
-
1866
- elseif buffer.type('blob')
1867
- let ref = expand("<cfile>")
1868
- try
1869
- let sha1 = buffer.repo().rev_parse(ref)
1870
- catch /^fugitive:/
1871
- endtry
1872
- if exists('sha1')
1873
- return s:Edit(a:mode,ref)
1874
- endif
1875
-
1876
- else
1877
-
1878
- " Index
1879
- if getline('.') =~# '^\d\{6\} \x\{40\} \d\t'
1880
- let ref = matchstr(getline('.'),'\x\{40\}')
1881
- let file = ':'.s:sub(matchstr(getline('.'),'\d\t.*'),'\t',':')
1882
- return s:Edit(a:mode,file)
1883
-
1884
- elseif getline('.') =~# '^#\trenamed:.* -> '
1885
- let file = '/'.matchstr(getline('.'),' -> \zs.*')
1886
- return s:Edit(a:mode,file)
1887
- elseif getline('.') =~# '^#\t[[:alpha:] ]\+: *.'
1888
- let file = '/'.matchstr(getline('.'),': *\zs.\{-\}\ze\%( (new commits)\)\=$')
1889
- return s:Edit(a:mode,file)
1890
- elseif getline('.') =~# '^#\t.'
1891
- let file = '/'.matchstr(getline('.'),'#\t\zs.*')
1892
- return s:Edit(a:mode,file)
1893
- elseif getline('.') =~# ': needs merge$'
1894
- let file = '/'.matchstr(getline('.'),'.*\ze: needs merge$')
1895
- return s:Edit(a:mode,file).'|Gdiff'
1896
-
1897
- elseif getline('.') ==# '# Not currently on any branch.'
1898
- return s:Edit(a:mode,'HEAD')
1899
- elseif getline('.') =~# '^# On branch '
1900
- let file = 'refs/heads/'.getline('.')[12:]
1901
- return s:Edit(a:mode,file)
1902
- elseif getline('.') =~# "^# Your branch .*'"
1903
- let file = matchstr(getline('.'),"'\\zs\\S\\+\\ze'")
1904
- return s:Edit(a:mode,file)
1905
- endif
1906
-
1907
- let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
1908
-
1909
- if getline('.') =~# '^ref: '
1910
- let ref = strpart(getline('.'),5)
1911
-
1912
- elseif getline('.') =~# '^parent \x\{40\}\>'
1913
- let ref = matchstr(getline('.'),'\x\{40\}')
1914
- let line = line('.')
1915
- let parent = 0
1916
- while getline(line) =~# '^parent '
1917
- let parent += 1
1918
- let line -= 1
1919
- endwhile
1920
- return s:Edit(a:mode,ref)
1921
-
1922
- elseif getline('.') =~ '^tree \x\{40\}$'
1923
- let ref = matchstr(getline('.'),'\x\{40\}')
1924
- if s:repo().rev_parse(myhash.':') == ref
1925
- let ref = myhash.':'
1926
- endif
1927
- return s:Edit(a:mode,ref)
1928
-
1929
- elseif getline('.') =~# '^object \x\{40\}$' && getline(line('.')+1) =~ '^type \%(commit\|tree\|blob\)$'
1930
- let ref = matchstr(getline('.'),'\x\{40\}')
1931
- let type = matchstr(getline(line('.')+1),'type \zs.*')
1932
-
1933
- elseif getline('.') =~# '^\l\{3,8\} '.myhash.'$'
1934
- return ''
1935
-
1936
- elseif getline('.') =~# '^\l\{3,8\} \x\{40\}\>'
1937
- let ref = matchstr(getline('.'),'\x\{40\}')
1938
- echoerr "warning: unknown context ".matchstr(getline('.'),'^\l*')
1939
-
1940
- elseif getline('.') =~# '^[+-]\{3\} [ab/]'
1941
- let ref = getline('.')[4:]
1942
-
1943
- elseif getline('.') =~# '^rename from '
1944
- let ref = 'a/'.getline('.')[12:]
1945
- elseif getline('.') =~# '^rename to '
1946
- let ref = 'b/'.getline('.')[10:]
1947
-
1948
- elseif getline('.') =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)'
1949
- let dref = matchstr(getline('.'),'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
1950
- let ref = matchstr(getline('.'),'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
1951
- let dcmd = 'Gdiff'
1952
-
1953
- elseif getline('.') =~# '^index ' && getline(line('.')-1) =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)'
1954
- let line = getline(line('.')-1)
1955
- let dref = matchstr(line,'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
1956
- let ref = matchstr(line,'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
1957
- let dcmd = 'Gdiff!'
1958
-
1959
- elseif line('$') == 1 && getline('.') =~ '^\x\{40\}$'
1960
- let ref = getline('.')
1961
- else
1962
- let ref = ''
1963
- endif
1964
-
1965
- if myhash ==# ''
1966
- let ref = s:sub(ref,'^a/','HEAD:')
1967
- let ref = s:sub(ref,'^b/',':0:')
1968
- if exists('dref')
1969
- let dref = s:sub(dref,'^a/','HEAD:')
1970
- endif
1971
- else
1972
- let ref = s:sub(ref,'^a/',myhash.'^:')
1973
- let ref = s:sub(ref,'^b/',myhash.':')
1974
- if exists('dref')
1975
- let dref = s:sub(dref,'^a/',myhash.'^:')
1976
- endif
1977
- endif
1978
-
1979
- if ref ==# '/dev/null'
1980
- " Empty blob
1981
- let ref = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'
1982
- endif
1983
-
1984
- if exists('dref')
1985
- return s:Edit(a:mode,ref) . '|'.dcmd.' '.s:fnameescape(dref)
1986
- elseif ref != ""
1987
- return s:Edit(a:mode,ref)
1988
- endif
1989
-
1990
- endif
1991
- return ''
1992
- catch /^fugitive:/
1993
- return 'echoerr v:errmsg'
1994
- endtry
1995
- endfunction
1996
-
1997
- " }}}1
1998
- " Statusline {{{1
1999
-
2000
- function! s:repo_head_ref() dict abort
2001
- return readfile(s:repo().dir('HEAD'))[0]
2002
- endfunction
2003
-
2004
- call s:add_methods('repo',['head_ref'])
2005
-
2006
- function! fugitive#statusline(...)
2007
- if !exists('b:git_dir')
2008
- return ''
2009
- endif
2010
- let status = ''
2011
- if s:buffer().commit() != ''
2012
- let status .= ':' . s:buffer().commit()[0:7]
2013
- endif
2014
- let head = s:repo().head_ref()
2015
- if head =~# '^ref: '
2016
- let status .= s:sub(head,'^ref: %(refs/%(heads/|remotes/|tags/)=)=','(').')'
2017
- elseif head =~# '^\x\{40\}$'
2018
- let status .= '('.head[0:7].')'
2019
- endif
2020
- if &statusline =~# '%[MRHWY]' && &statusline !~# '%[mrhwy]'
2021
- return ',GIT'.status
2022
- else
2023
- return '[Git'.status.']'
2024
- endif
2025
- endfunction
2026
-
2027
- function! s:repo_config(conf) dict abort
2028
- return matchstr(system(s:repo().git_command('config').' '.a:conf),"[^\r\n]*")
2029
- endfun
2030
-
2031
- function! s:repo_user() dict abort
2032
- let username = s:repo().config('user.name')
2033
- let useremail = s:repo().config('user.email')
2034
- return username.' <'.useremail.'>'
2035
- endfun
2036
-
2037
- call s:add_methods('repo',['config', 'user'])
2038
-
2039
- " }}}1
2040
-
2041
- " vim:set ft=vim ts=8 sw=2 sts=2: