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
|
let raw = remote
|
||||||
endif
|
endif
|
||||||
|
|
||||||
for Handler in g:fugitive_experimental_browse_handlers
|
for Handler in g:fugitive_browse_handlers
|
||||||
let url = call(Handler, [s:repo(),raw,rev,commit,path,type,a:line1,a:count])
|
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)
|
if !empty(url)
|
||||||
break
|
break
|
||||||
endif
|
endif
|
||||||
@ -2199,17 +2206,20 @@ function! s:Browse(bang,line1,count,...) abort
|
|||||||
endtry
|
endtry
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort
|
function! s:github_url(repo, opts, ...) abort
|
||||||
let path = a:path
|
if a:0 || type(a:opts) != type({})
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
let domain_pattern = 'github\.com'
|
let domain_pattern = 'github\.com'
|
||||||
let domains = exists('g:fugitive_github_domains') ? g:fugitive_github_domains : []
|
let domains = exists('g:fugitive_github_domains') ? g:fugitive_github_domains : []
|
||||||
for domain in domains
|
for domain in domains
|
||||||
let domain_pattern .= '\|' . escape(split(domain, '://')[-1], '.')
|
let domain_pattern .= '\|' . escape(split(domain, '://')[-1], '.')
|
||||||
endfor
|
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 ==# ''
|
if repo ==# ''
|
||||||
return ''
|
return ''
|
||||||
endif
|
endif
|
||||||
|
let path = a:opts.path
|
||||||
if index(domains, 'http://' . matchstr(repo, '^[^:/]*')) >= 0
|
if index(domains, 'http://' . matchstr(repo, '^[^:/]*')) >= 0
|
||||||
let root = 'http://' . s:sub(repo,':','/')
|
let root = 'http://' . s:sub(repo,':','/')
|
||||||
else
|
else
|
||||||
@ -2229,27 +2239,27 @@ function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort
|
|||||||
elseif path =~# '^\.git\>'
|
elseif path =~# '^\.git\>'
|
||||||
return root
|
return root
|
||||||
endif
|
endif
|
||||||
if a:rev =~# '^[[:alnum:]._-]\+:'
|
if a:opts.revision =~# '^[[:alnum:]._-]\+:'
|
||||||
let commit = matchstr(a:rev,'^[^:]*')
|
let commit = matchstr(a:opts.revision,'^[^:]*')
|
||||||
elseif a:commit =~# '^\d\=$'
|
elseif a:opts.commit =~# '^\d\=$'
|
||||||
let local = matchstr(a:repo.head_ref(),'\<refs/heads/\zs.*')
|
let local = matchstr(a:repo.head_ref(),'\<refs/heads/\zs.*')
|
||||||
let commit = a:repo.git_chomp('config','branch.'.local.'.merge')[11:-1]
|
let commit = a:repo.git_chomp('config','branch.'.local.'.merge')[11:-1]
|
||||||
if commit ==# ''
|
if commit ==# ''
|
||||||
let commit = local
|
let commit = local
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
let commit = a:commit
|
let commit = a:opts.commit
|
||||||
endif
|
endif
|
||||||
if a:type == 'tree'
|
if a:opts.type == 'tree'
|
||||||
let url = s:sub(root . '/tree/' . commit . '/' . path,'/$','')
|
let url = s:sub(root . '/tree/' . commit . '/' . path,'/$','')
|
||||||
elseif a:type == 'blob'
|
elseif a:opts.type == 'blob'
|
||||||
let url = root . '/blob/' . commit . '/' . path
|
let url = root . '/blob/' . commit . '/' . path
|
||||||
if a:line2 > 0 && a:line1 == a:line2
|
if get(a:opts, 'line2') && a:opts.line1 == a:opts.line2
|
||||||
let url .= '#L' . a:line1
|
let url .= '#L' . a:opts.line1
|
||||||
elseif a:line2 > 0
|
elseif get(a:opts, 'line2')
|
||||||
let url .= '#L' . a:line1 . '-' . a:line2
|
let url .= '#L' . a:opts.line1 . '-' . a:opts.line2
|
||||||
endif
|
endif
|
||||||
elseif a:type == 'tag'
|
elseif a:opts.type == 'tag'
|
||||||
let commit = matchstr(getline(3),'^tag \zs.*')
|
let commit = matchstr(getline(3),'^tag \zs.*')
|
||||||
let url = root . '/tree/' . commit
|
let url = root . '/tree/' . commit
|
||||||
else
|
else
|
||||||
@ -2258,52 +2268,52 @@ function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort
|
|||||||
return url
|
return url
|
||||||
endfunction
|
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')
|
let output = a:repo.git_chomp('instaweb','-b','unknown')
|
||||||
if output =~# 'http://'
|
if output =~# 'http://'
|
||||||
let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:repo.dir(),':t')
|
let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:repo.dir(),':t')
|
||||||
else
|
else
|
||||||
return ''
|
return ''
|
||||||
endif
|
endif
|
||||||
if a:path =~# '^\.git/refs/.'
|
if a:opts.path =~# '^\.git/refs/.'
|
||||||
return root . ';a=shortlog;h=' . matchstr(a:path,'^\.git/\zs.*')
|
return root . ';a=shortlog;h=' . matchstr(a:opts.path,'^\.git/\zs.*')
|
||||||
elseif a:path =~# '^\.git\>'
|
elseif a:opts.path =~# '^\.git\>'
|
||||||
return root
|
return root
|
||||||
endif
|
endif
|
||||||
let url = root
|
let url = root
|
||||||
if a:commit =~# '^\x\{40\}$'
|
if a:opts.commit =~# '^\x\{40\}$'
|
||||||
if a:type ==# 'commit'
|
if a:opts.type ==# 'commit'
|
||||||
let url .= ';a=commit'
|
let url .= ';a=commit'
|
||||||
endif
|
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
|
else
|
||||||
if a:type ==# 'blob'
|
if a:opts.type ==# 'blob'
|
||||||
let tmp = tempname()
|
let tmp = tempname()
|
||||||
silent execute 'write !'.a:repo.git_command('hash-object','-w','--stdin').' > '.tmp
|
silent execute 'write !'.a:repo.git_command('hash-object','-w','--stdin').' > '.tmp
|
||||||
let url .= ';h=' . readfile(tmp)[0]
|
let url .= ';h=' . readfile(tmp)[0]
|
||||||
else
|
else
|
||||||
try
|
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:/
|
catch /^fugitive:/
|
||||||
call s:throw('fugitive: cannot browse uncommitted file')
|
call s:throw('fugitive: cannot browse uncommitted file')
|
||||||
endtry
|
endtry
|
||||||
endif
|
endif
|
||||||
let root .= ';hb=' . matchstr(a:repo.head_ref(),'[^ ]\+$')
|
let root .= ';hb=' . matchstr(a:repo.head_ref(),'[^ ]\+$')
|
||||||
endif
|
endif
|
||||||
if a:path !=# ''
|
if a:opts.path !=# ''
|
||||||
let url .= ';f=' . a:path
|
let url .= ';f=' . a:opts.path
|
||||||
endif
|
endif
|
||||||
if a:0 && a:1
|
if get(a:opts, 'line1')
|
||||||
let url .= '#l' . a:1
|
let url .= '#l' . a:opts.line1
|
||||||
endif
|
endif
|
||||||
return url
|
return url
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
if !exists('g:fugitive_experimental_browse_handlers')
|
if !exists('g:fugitive_browse_handlers')
|
||||||
let g:fugitive_experimental_browse_handlers = []
|
let g:fugitive_browse_handlers = []
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call extend(g:fugitive_experimental_browse_handlers,
|
call extend(g:fugitive_browse_handlers,
|
||||||
\ [s:function('s:github_url'), s:function('s:instaweb_url')])
|
\ [s:function('s:github_url'), s:function('s:instaweb_url')])
|
||||||
|
|
||||||
" Section: File access
|
" Section: File access
|
||||||
|
Loading…
x
Reference in New Issue
Block a user