utils 0.0.67 → 0.0.68

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.
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: