84 lines
2.3 KiB
Lua
84 lines
2.3 KiB
Lua
local function file_exists(file_path)
|
|
local file = io.open(file_path, "rb")
|
|
if file then file:close() end
|
|
return file ~= nil
|
|
end
|
|
|
|
local remote_prefix_patterns = {'ssh://', 'http[s]?://', '%w+@'}
|
|
|
|
local function transform_url(remote)
|
|
for _, pattern in pairs(remote_prefix_patterns) do
|
|
local regex_pattern = string.format('^%s(.*)', pattern)
|
|
if remote:match(regex_pattern) then
|
|
local _url = remote:match(regex_pattern, 1)
|
|
_url = _url:gsub('(:)(%a+)', '/%2')
|
|
_url = _url:gsub('.git$', '')
|
|
|
|
if not _url:match('^http[s]?://') then
|
|
return string.format('%s%s', 'https://', _url)
|
|
end
|
|
|
|
return _url
|
|
end
|
|
end
|
|
end
|
|
|
|
-- TODO: add more providers
|
|
-- TODO: add feature to specify provider
|
|
local provider_mapping = {
|
|
['github'] = '%s/blob/%s/%s#L%i',
|
|
['bitbucket'] = '%s/src/%s/%s#lines-%i',
|
|
['forgejo'] = '%s/src/commit/%s/%s#L%i',
|
|
}
|
|
|
|
local function get_provider_template(remote)
|
|
local transformed_url = transform_url(remote)
|
|
|
|
if not transformed_url then return end
|
|
|
|
for domain, template_string in pairs(provider_mapping) do
|
|
if transformed_url:match(domain) then
|
|
return transformed_url, template_string
|
|
end
|
|
end
|
|
end
|
|
|
|
local function source_open()
|
|
local git_conf_path = '.git/config'
|
|
|
|
-- TODO: determine based on recursively traversing upwards in path
|
|
if not file_exists(git_conf_path) then return end
|
|
|
|
local _remote_output = io.popen('git remote get-url origin', 'r')
|
|
|
|
-- TODO: test with other refs
|
|
local _commit_output = io.popen('git show --pretty=%H HEAD', 'r')
|
|
|
|
if _remote_output == nil or _commit_output == nil then return end
|
|
|
|
local line_number = unpack(vim.api.nvim_win_get_cursor(0))
|
|
local filepath = vim.api.nvim_buf_get_name(0)
|
|
local relative_filepath = vim.fn.fnamemodify(filepath, ':.')
|
|
|
|
local remote = _remote_output:read()
|
|
local branch = _commit_output:read()
|
|
|
|
local transformed_url, template_string = get_provider_template(remote)
|
|
|
|
for _, variable in pairs({ filepath, transformed_url, template_string }) do
|
|
if variable == nil then
|
|
return
|
|
end
|
|
end
|
|
|
|
local template_args = { transformed_url, branch, relative_filepath, line_number }
|
|
local url = template_string:format(unpack(template_args))
|
|
|
|
os.execute(('xdg-open %s'):format(url))
|
|
end
|
|
|
|
local function setup(opts)
|
|
vim.api.nvim_create_user_command('SourceOpen', source_open, {})
|
|
end
|
|
|
|
return { setup = setup }
|