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.
This commit is contained in:
parent
5d1c219ee5
commit
5aaa65736d
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user