commit 5aaa65736d9cc99c3f8dbd0c24db9d8660b0c236 (tree)
parent 5d1c219ee5e26f518d9a29c575522e81fbd0f762
Author: Tim Pope <code@tpope.net>
Date: Tue, 22 Jul 2014 00:17:43 -0400
Browse handler API
Taking experimental out of the name, but small tweaks may occur before
then next release.
For future compatibility, any third party handlers should bail and
return an empty string if any of the following are true:
* More than 2 arguments are given.
* The second argument isn't a dictionary.
* The dictionary doesn't contain a "remote" key.
Closes #445.
Diffstat:
| M | plugin/fugitive.vim | | | 74 | ++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
1 file changed, 42 insertions(+), 32 deletions(-)
diff --git a/plugin/fugitive.vim b/plugin/fugitive.vim
@@ -2175,8 +2175,15 @@ function! s:Browse(bang,line1,count,...) abort
let raw = remote
endif
- for Handler in g:fugitive_experimental_browse_handlers
- let url = call(Handler, [s:repo(),raw,rev,commit,path,type,a:line1,a:count])
+ for Handler in g:fugitive_browse_handlers
+ let url = call(Handler, [s:repo(), {
+ \ 'remote': raw,
+ \ 'revision': rev,
+ \ 'commit': commit,
+ \ 'path': path,
+ \ 'type': type,
+ \ 'line1': a:line1,
+ \ 'line2': a:count}])
if !empty(url)
break
endif
@@ -2199,17 +2206,20 @@ function! s:Browse(bang,line1,count,...) abort
endtry
endfunction
-function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort
- let path = a:path
+function! s:github_url(repo, opts, ...) abort
+ if a:0 || type(a:opts) != type({})
+ return ''
+ endif
let domain_pattern = 'github\.com'
let domains = exists('g:fugitive_github_domains') ? g:fugitive_github_domains : []
for domain in domains
let domain_pattern .= '\|' . escape(split(domain, '://')[-1], '.')
endfor
- let repo = matchstr(a:url,'^\%(https\=://\|git://\|git@\)\=\zs\('.domain_pattern.'\)[/:].\{-\}\ze\%(\.git\)\=$')
+ let repo = matchstr(get(a:opts, 'remote'), '^\%(https\=://\|git://\|git@\)\=\zs\('.domain_pattern.'\)[/:].\{-\}\ze\%(\.git\)\=$')
if repo ==# ''
return ''
endif
+ let path = a:opts.path
if index(domains, 'http://' . matchstr(repo, '^[^:/]*')) >= 0
let root = 'http://' . s:sub(repo,':','/')
else
@@ -2229,27 +2239,27 @@ function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort
elseif path =~# '^\.git\>'
return root
endif
- if a:rev =~# '^[[:alnum:]._-]\+:'
- let commit = matchstr(a:rev,'^[^:]*')
- elseif a:commit =~# '^\d\=$'
+ if a:opts.revision =~# '^[[:alnum:]._-]\+:'
+ let commit = matchstr(a:opts.revision,'^[^:]*')
+ elseif a:opts.commit =~# '^\d\=$'
let local = matchstr(a:repo.head_ref(),'\<refs/heads/\zs.*')
let commit = a:repo.git_chomp('config','branch.'.local.'.merge')[11:-1]
if commit ==# ''
let commit = local
endif
else
- let commit = a:commit
+ let commit = a:opts.commit
endif
- if a:type == 'tree'
+ if a:opts.type == 'tree'
let url = s:sub(root . '/tree/' . commit . '/' . path,'/$','')
- elseif a:type == 'blob'
+ elseif a:opts.type == 'blob'
let url = root . '/blob/' . commit . '/' . path
- if a:line2 > 0 && a:line1 == a:line2
- let url .= '#L' . a:line1
- elseif a:line2 > 0
- let url .= '#L' . a:line1 . '-' . a:line2
+ if get(a:opts, 'line2') && a:opts.line1 == a:opts.line2
+ let url .= '#L' . a:opts.line1
+ elseif get(a:opts, 'line2')
+ let url .= '#L' . a:opts.line1 . '-' . a:opts.line2
endif
- elseif a:type == 'tag'
+ elseif a:opts.type == 'tag'
let commit = matchstr(getline(3),'^tag \zs.*')
let url = root . '/tree/' . commit
else
@@ -2258,52 +2268,52 @@ function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort
return url
endfunction
-function! s:instaweb_url(repo,rev,commit,path,type,...) abort
+function! s:instaweb_url(repo, opts) abort
let output = a:repo.git_chomp('instaweb','-b','unknown')
if output =~# 'http://'
let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:repo.dir(),':t')
else
return ''
endif
- if a:path =~# '^\.git/refs/.'
- return root . ';a=shortlog;h=' . matchstr(a:path,'^\.git/\zs.*')
- elseif a:path =~# '^\.git\>'
+ if a:opts.path =~# '^\.git/refs/.'
+ return root . ';a=shortlog;h=' . matchstr(a:opts.path,'^\.git/\zs.*')
+ elseif a:opts.path =~# '^\.git\>'
return root
endif
let url = root
- if a:commit =~# '^\x\{40\}$'
- if a:type ==# 'commit'
+ if a:opts.commit =~# '^\x\{40\}$'
+ if a:opts.type ==# 'commit'
let url .= ';a=commit'
endif
- let url .= ';h=' . a:repo.rev_parse(a:commit . (a:path == '' ? '' : ':' . a:path))
+ let url .= ';h=' . a:repo.rev_parse(a:opts.commit . (a:opts.path == '' ? '' : ':' . a:opts.path))
else
- if a:type ==# 'blob'
+ if a:opts.type ==# 'blob'
let tmp = tempname()
silent execute 'write !'.a:repo.git_command('hash-object','-w','--stdin').' > '.tmp
let url .= ';h=' . readfile(tmp)[0]
else
try
- let url .= ';h=' . a:repo.rev_parse((a:commit == '' ? 'HEAD' : ':' . a:commit) . ':' . a:path)
+ let url .= ';h=' . a:repo.rev_parse((a:opts.commit == '' ? 'HEAD' : ':' . a:opts.commit) . ':' . a:opts.path)
catch /^fugitive:/
call s:throw('fugitive: cannot browse uncommitted file')
endtry
endif
let root .= ';hb=' . matchstr(a:repo.head_ref(),'[^ ]\+$')
endif
- if a:path !=# ''
- let url .= ';f=' . a:path
+ if a:opts.path !=# ''
+ let url .= ';f=' . a:opts.path
endif
- if a:0 && a:1
- let url .= '#l' . a:1
+ if get(a:opts, 'line1')
+ let url .= '#l' . a:opts.line1
endif
return url
endfunction
-if !exists('g:fugitive_experimental_browse_handlers')
- let g:fugitive_experimental_browse_handlers = []
+if !exists('g:fugitive_browse_handlers')
+ let g:fugitive_browse_handlers = []
endif
-call extend(g:fugitive_experimental_browse_handlers,
+call extend(g:fugitive_browse_handlers,
\ [s:function('s:github_url'), s:function('s:instaweb_url')])
" Section: File access