Skip to content

Commit 4d29c1d

Browse files
committed
Provide for retrieving parsed remote URL
The plan is to expose this as FugitiveRemote(), but let's give it some bake time before making it official.
1 parent 93f41ac commit 4d29c1d

File tree

1 file changed

+73
-42
lines changed

1 file changed

+73
-42
lines changed

autoload/fugitive.vim

Lines changed: 73 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,39 +1272,82 @@ function! s:UrlParse(url) abort
12721272
return url
12731273
endfunction
12741274

1275-
function! s:ResolveRemote(url) abort
1275+
function! s:RemoteResolve(url, flags) abort
12761276
let remote = s:UrlParse(a:url)
1277-
if remote.scheme =~# '^https\=$'
1277+
if remote.scheme =~# '^https\=$' && index(a:flags, ':nohttp') < 0
12781278
let headers = fugitive#RemoteHttpHeaders(remote.scheme . '://' . remote.authority . remote.path)
12791279
let loc = matchstr(get(headers, 'location', ''), '^https\=://.\{-\}\ze/info/refs?')
12801280
if len(loc)
12811281
let remote = s:UrlParse(loc)
12821282
else
1283-
let remote.http_headers = headers
1283+
let remote.headers = headers
12841284
endif
12851285
elseif remote.scheme ==# 'ssh'
12861286
let remote.authority = fugitive#SshHostAlias(remote.authority)
12871287
endif
12881288
return remote
12891289
endfunction
12901290

1291-
function! fugitive#ResolveRemote(url) abort
1292-
let remote = s:ResolveRemote(a:url)
1293-
if remote.scheme ==# 'file' || remote.scheme ==# ''
1294-
return remote.path
1295-
elseif remote.path =~# '^/'
1296-
return remote.scheme . '://' . remote.authority . remote.path
1297-
elseif remote.path =~# '^\~'
1298-
return remote.scheme . '://' . remote.authority . '/' . remote.path
1299-
elseif remote.scheme ==# 'ssh' && remote.authority !~# ':'
1300-
return remote.authority . ':' . remote.path
1291+
function! s:ConfigLengthSort(i1, i2) abort
1292+
return len(a:i2[0]) - len(a:i1[0])
1293+
endfunction
1294+
1295+
function! s:RemoteCallback(config, into, flags, cb) abort
1296+
if a:into.remote_name =~# '^\.\=$'
1297+
let a:into.remote_name = s:RemoteDefault(a:config)
1298+
endif
1299+
let url = a:into.remote_name
1300+
1301+
if url ==# '.git'
1302+
let url = s:GitDir(a:config)
1303+
elseif url !~# ':\|^/\|^\a:[\/]\|^\.\.\=/'
1304+
let url = FugitiveConfigGet('remote.' . url . '.url', a:config)
1305+
endif
1306+
let instead_of = []
1307+
for [k, vs] in items(fugitive#ConfigGetRegexp('^url\.\zs.\{-\}\ze\.insteadof$', a:config))
1308+
for v in vs
1309+
call add(instead_of, [v, k])
1310+
endfor
1311+
endfor
1312+
call sort(instead_of, 's:ConfigLengthSort')
1313+
for [orig, replacement] in instead_of
1314+
if strpart(url, 0, len(orig)) ==# orig
1315+
let url = replacement . strpart(url, len(orig))
1316+
break
1317+
endif
1318+
endfor
1319+
if index(a:flags, ':noresolve') < 0
1320+
call extend(a:into, s:RemoteResolve(url, a:flags))
1321+
else
1322+
call extend(a:into, s:UrlParse(url))
1323+
endif
1324+
let a:into.user = matchstr(a:into.authority, '.\{-\}\ze@', '', '')
1325+
let a:into.host = substitute(a:into.authority, '.\{-\}@', '', '')
1326+
let a:into.hostname = substitute(a:into.host, ':\d\+$', '', '')
1327+
let a:into.port = matchstr(a:into.host, ':\zs\d\+$', '', '')
1328+
if a:into.path =~# '^/'
1329+
let a:into.url = a:into.scheme . '://' . a:into.authority . a:into.path
1330+
elseif a:into.path =~# '^\~'
1331+
let a:into.url = a:into.scheme . '://' . a:into.authority . '/' . a:into.path
1332+
elseif a:into.scheme ==# 'ssh' && a:into.authority !~# ':'
1333+
let a:into.url = a:into.authority . ':' . a:into.path
13011334
else
1302-
return a:url
1335+
let a:into.url = url
1336+
endif
1337+
if len(a:cb)
1338+
call call(a:cb[0], [a:into] + a:cb[1:-1])
13031339
endif
13041340
endfunction
13051341

1306-
function! s:ConfigLengthSort(i1, i2) abort
1307-
return len(a:i2[0]) - len(a:i1[0])
1342+
function! s:Remote(dir, remote, flags, cb) abort
1343+
let into = {'remote_name': a:remote, 'git_dir': s:GitDir(a:dir)}
1344+
let config = fugitive#Config(a:dir, function('s:RemoteCallback'), into, a:flags, a:cb)
1345+
if len(a:cb)
1346+
return config
1347+
else
1348+
call fugitive#Wait(config)
1349+
return into
1350+
endif
13081351
endfunction
13091352

13101353
function! s:RemoteParseArgs(args) abort
@@ -1344,34 +1387,22 @@ function! s:RemoteParseArgs(args) abort
13441387
return [dir_or_config, remote, flags, cb]
13451388
endfunction
13461389

1390+
function! fugitive#Remote(...) abort
1391+
let [dir_or_config, remote, flags, cb] = s:RemoteParseArgs(a:000)
1392+
return s:Remote(dir_or_config, remote, flags, cb)
1393+
endfunction
1394+
1395+
function! s:RemoteUrlCallback(remote, callback) abort
1396+
return call(a:callback[0], [a:remote.url] + a:callback[1:-1])
1397+
endfunction
1398+
13471399
function! fugitive#RemoteUrl(...) abort
1348-
let [dir_or_config, url, flags, cb] = s:RemoteParseArgs(a:000)
1349-
let config = fugitive#Config(dir_or_config)
1350-
if url =~# '^\.\=$'
1351-
let url = s:RemoteDefault(config)
1352-
endif
1353-
if url ==# '.git'
1354-
let url = s:GitDir(config)
1355-
elseif url !~# ':\|^/\|^\.\.\=/'
1356-
let url = FugitiveConfigGet('remote.' . url . '.url', config)
1400+
let [dir_or_config, remote, flags, cb] = s:RemoteParseArgs(a:000)
1401+
if len(cb)
1402+
let cb = [function('s:RemoteUrlCallback'), cb]
13571403
endif
1358-
let instead_of = []
1359-
for [k, vs] in items(fugitive#ConfigGetRegexp('^url\.\zs.\{-\}\ze\.insteadof$', config))
1360-
for v in vs
1361-
call add(instead_of, [v, k])
1362-
endfor
1363-
endfor
1364-
call sort(instead_of, 's:ConfigLengthSort')
1365-
for [orig, replacement] in instead_of
1366-
if strpart(url, 0, len(orig)) ==# orig
1367-
let url = replacement . strpart(url, len(orig))
1368-
break
1369-
endif
1370-
endfor
1371-
if index(flags, 1) < 0 && index(flags, get(v:, 'true', 1)) < 0 && index(flags, ':noresolve') < 0
1372-
let url = fugitive#ResolveRemote(url)
1373-
endif
1374-
return url
1404+
let remote = s:Remote(dir_or_config, remote, flags, cb)
1405+
return get(remote, 'url', remote)
13751406
endfunction
13761407

13771408
" Section: Quickfix

0 commit comments

Comments
 (0)