From 9964bfdaea87c28a82ffc8a395ba9b700d78254b Mon Sep 17 00:00:00 2001 From: Marco Kellershoff Date: Thu, 4 Jul 2024 23:47:24 +0200 Subject: [PATCH] feat: support multiple portals --- lua/ndoo/config.lua | 42 ++++++++ lua/ndoo/github/init.lua | 6 -- lua/ndoo/helper/init.lua | 104 -------------------- lua/ndoo/helper/json.lua | 147 ---------------------------- lua/ndoo/init.lua | 170 ++++++++++++++++++++++++++------- lua/ndoo/portals/bitbucket.lua | 114 ++++++++++++++++++++++ lua/ndoo/portals/github.lua | 105 ++++++++++++++++++++ lua/ndoo/portals/gitlab.lua | 6 ++ lua/ndoo/portals/init.lua | 39 ++++++++ 9 files changed, 443 insertions(+), 290 deletions(-) create mode 100644 lua/ndoo/config.lua delete mode 100644 lua/ndoo/github/init.lua delete mode 100644 lua/ndoo/helper/json.lua create mode 100644 lua/ndoo/portals/bitbucket.lua create mode 100644 lua/ndoo/portals/github.lua create mode 100644 lua/ndoo/portals/gitlab.lua create mode 100644 lua/ndoo/portals/init.lua diff --git a/lua/ndoo/config.lua b/lua/ndoo/config.lua new file mode 100644 index 0000000..58d04f9 --- /dev/null +++ b/lua/ndoo/config.lua @@ -0,0 +1,42 @@ +local M = {} +local DEFAULT_CONFIG = {} +local UV = vim.loop + +local function get_os_path_separator() + if vim.fn.has("win32") == 1 then + return "\\" + else + return "/" + end +end + +M.PS = get_os_path_separator() + +M.get_config = function() + return config +end + +M.set_config = function(config) + config = config or {} + config = vim.tbl_deep_extend("force", DEFAULT_CONFIG, config) +end + +M.get_config_dir = function() + local config_dir = vim.fn.stdpath("config") + return config_dir:match("(.*)" .. M.PS .. ".*") .. M.PS .. "ndoo" +end + +M.get_config_json = function() + local config_dir = M.get_config_dir() + local config_file = config_dir .. M.PS .. "config.json" + local config = {} + if vim.fn.filereadable(config_file) == 1 then + local file = io.open(config_file, "r") + local content = file:read("*a") + config = vim.fn.json_decode(content) + file:close() + end + return config +end + +return M diff --git a/lua/ndoo/github/init.lua b/lua/ndoo/github/init.lua deleted file mode 100644 index fa72c0b..0000000 --- a/lua/ndoo/github/init.lua +++ /dev/null @@ -1,6 +0,0 @@ -local M = {} - -M.base_url = "https://github.com/" - -return M - diff --git a/lua/ndoo/helper/init.lua b/lua/ndoo/helper/init.lua index e85898b..921a37b 100644 --- a/lua/ndoo/helper/init.lua +++ b/lua/ndoo/helper/init.lua @@ -1,11 +1,3 @@ -local telescope_pickers = require "telescope.pickers" -local telescope_finders = require "telescope.finders" -local telescope_conf = require("telescope.config").values -local telescope_actions = require "telescope.actions" -local telescope_action_state = require "telescope.actions.state" -local telescope_themes = require("telescope.themes") -local telescope_theme_dropdown = telescope_themes.get_dropdown{} -local json = require("ndoo.helper.json") local pickers = require("ndoo.helper.pickers") local M = {} @@ -18,52 +10,6 @@ function M.get_current_git_commit_hash() return commit_hash end -function M.show_github_labels_picker(cb_func) - local jsonstr = vim.fn.system("gh label list --json name,description,url -L 30") - local pulls = json.parse(jsonstr) - - pickers.generic_table_picker({ - prompt_title = "Pick a label", - dropdown = true, - results = pulls, - entry_maker_value_key = "url", - entry_maker_display_key = "name", - entry_maker_ordinal_key = "name", - cb_func = cb_func, - }) -end - -function M.show_github_pull_picker(cb_func) - local jsonstr = vim.fn.system("gh pr list --json number,title,body,updatedAt -L 2000") - local pulls = json.parse(jsonstr) - - pickers.generic_table_picker({ - prompt_title = "Pick a pull", - results = pulls, - entry_maker_value_key = "number", - entry_maker_display_key = "title", - entry_maker_ordinal_key = "title", - preview = true, - previewer_value_key = "body", - cb_func = cb_func, - }) -end - -function M.show_github_issues_picker(cb_func) - local jsonstr = vim.fn.system("gh issue list --json number,title,body,updatedAt -L 2000") - local issues = json.parse(jsonstr) - - pickers.generic_table_picker({ - prompt_title = "Pick an issue", - results = issues, - entry_maker_value_key = "number", - entry_maker_display_key = "title", - entry_maker_ordinal_key = "title", - preview = true, - previewer_value_key = "body", - cb_func = cb_func, - }) -end function M.get_current_git_branch() local branch = vim.fn.systemlist("git branch --show-current")[1] @@ -108,55 +54,5 @@ function M.open_url_in_browser(url) end end -function M.get_github_remote_url(remote) - if remote == nil then - remote = "origin" - end - local url = vim.fn.systemlist("git remote get-url " .. remote)[1] - if url == "" then - return nil - end - return url -end - -function M.get_github_repo_protocol() - local url = M.get_github_remote_url() - if url:match("^git@") then - return "ssh" - end - if url:match("^https://") then - return "https" - end - return nil -end - -function M.get_github_repo_name(remote) - local url = M.get_github_remote_url(remote) - if url == nil then - return nil - end - local repo_name = url:match("^.+/(.+)$") - if repo_name == nil then - return nil - end - repo_name = repo_name:gsub("%.git$", "") - return repo_name -end - -function M.get_github_repo_owner(remote) - local url = M.get_github_remote_url(remote) - if url == nil then - return nil - end - local repo_owner = nil - local repo_protocol = M.get_github_repo_protocol(remote) - if repo_protocol == "ssh" then - repo_owner = url:match("^.+:(.+)/.+$") - end - if repo_protocol == "https" then - repo_owner = url:match("^.+/(.+)/.+$") - end - return repo_owner -end return M diff --git a/lua/ndoo/helper/json.lua b/lua/ndoo/helper/json.lua deleted file mode 100644 index 57b4ce0..0000000 --- a/lua/ndoo/helper/json.lua +++ /dev/null @@ -1,147 +0,0 @@ -local M = {} - --- Internal functions. - -local function kind_of(obj) - if type(obj) ~= 'table' then return type(obj) end - local i = 1 - for _ in pairs(obj) do - if obj[i] ~= nil then i = i + 1 else return 'table' end - end - if i == 1 then return 'table' else return 'array' end -end - -local function escape_str(s) - local in_char = {'\\', '"', '/', '\b', '\f', '\n', '\r', '\t'} - local out_char = {'\\', '"', '/', 'b', 'f', 'n', 'r', 't'} - for i, c in ipairs(in_char) do - s = s:gsub(c, '\\' .. out_char[i]) - end - return s -end - --- Returns pos, did_find; there are two cases: --- 1. Delimiter found: pos = pos after leading space + delim; did_find = true. --- 2. Delimiter not found: pos = pos after leading space; did_find = false. --- This throws an error if err_if_missing is true and the delim is not found. -local function skip_delim(str, pos, delim, err_if_missing) - pos = pos + #str:match('^%s*', pos) - if str:sub(pos, pos) ~= delim then - if err_if_missing then - error('Expected ' .. delim .. ' near position ' .. pos) - end - return pos, false - end - return pos + 1, true -end - --- Expects the given pos to be the first character after the opening quote. --- Returns val, pos; the returned pos is after the closing quote character. -local function parse_str_val(str, pos, val) - val = val or '' - local early_end_error = 'End of input found while parsing string.' - if pos > #str then error(early_end_error) end - local c = str:sub(pos, pos) - if c == '"' then return val, pos + 1 end - if c ~= '\\' then return parse_str_val(str, pos + 1, val .. c) end - -- We must have a \ character. - local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'} - local nextc = str:sub(pos + 1, pos + 1) - if not nextc then error(early_end_error) end - return parse_str_val(str, pos + 2, val .. (esc_map[nextc] or nextc)) -end - --- Returns val, pos; the returned pos is after the number's final character. -local function parse_num_val(str, pos) - local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos) - local val = tonumber(num_str) - if not val then error('Error parsing number at position ' .. pos .. '.') end - return val, pos + #num_str -end - - --- Public values and functions. - -function M.stringify(obj, as_key) - local s = {} -- We'll build the string as an array of strings to be concatenated. - local kind = kind_of(obj) -- This is 'array' if it's an array or type(obj) otherwise. - if kind == 'array' then - if as_key then error('Can\'t encode array as key.') end - s[#s + 1] = '[' - for i, val in ipairs(obj) do - if i > 1 then s[#s + 1] = ', ' end - s[#s + 1] = M.stringify(val) - end - s[#s + 1] = ']' - elseif kind == 'table' then - if as_key then error('Can\'t encode table as key.') end - s[#s + 1] = '{' - for k, v in pairs(obj) do - if #s > 1 then s[#s + 1] = ', ' end - s[#s + 1] = M.stringify(k, true) - s[#s + 1] = ':' - s[#s + 1] = M.stringify(v) - end - s[#s + 1] = '}' - elseif kind == 'string' then - return '"' .. escape_str(obj) .. '"' - elseif kind == 'number' then - if as_key then return '"' .. tostring(obj) .. '"' end - return tostring(obj) - elseif kind == 'boolean' then - return tostring(obj) - elseif kind == 'nil' then - return 'null' - else - error('Unjsonifiable type: ' .. kind .. '.') - end - return table.concat(s) -end - -M.null = {} -- This is a one-off table to represent the null value. - -function M.parse(str, pos, end_delim) - pos = pos or 1 - if pos > #str then error('Reached unexpected end of input.') end - local pos = pos + #str:match('^%s*', pos) -- Skip whitespace. - local first = str:sub(pos, pos) - if first == '{' then -- Parse an object. - local obj, key, delim_found = {}, true, true - pos = pos + 1 - while true do - key, pos = M.parse(str, pos, '}') - if key == nil then return obj, pos end - if not delim_found then error('Comma missing between object items.') end - pos = skip_delim(str, pos, ':', true) -- true -> error if missing. - obj[key], pos = M.parse(str, pos) - pos, delim_found = skip_delim(str, pos, ',') - end - elseif first == '[' then -- Parse an array. - local arr, val, delim_found = {}, true, true - pos = pos + 1 - while true do - val, pos = M.parse(str, pos, ']') - if val == nil then return arr, pos end - if not delim_found then error('Comma missing between array items.') end - arr[#arr + 1] = val - pos, delim_found = skip_delim(str, pos, ',') - end - elseif first == '"' then -- Parse a string. - return parse_str_val(str, pos + 1) - elseif first == '-' or first:match('%d') then -- Parse a number. - return parse_num_val(str, pos) - elseif first == end_delim then -- End of an object or array. - return nil, pos + 1 - else -- Parse true, false, or null. - local literals = {['true'] = true, ['false'] = false, ['null'] = M.null} - for lit_str, lit_val in pairs(literals) do - local lit_end = pos + #lit_str - 1 - if str:sub(pos, lit_end) == lit_str then return lit_val, lit_end + 1 end - end - local pos_info_str = 'position ' .. pos .. ': ' .. str:sub(pos, pos + 10) - error('Invalid json syntax starting at ' .. pos_info_str) - end -end - -return M - diff --git a/lua/ndoo/init.lua b/lua/ndoo/init.lua index f36e21e..076831b 100644 --- a/lua/ndoo/init.lua +++ b/lua/ndoo/init.lua @@ -1,14 +1,33 @@ local HELPER = require("ndoo.helper") -local GITHUB = require("ndoo.github") +local PORTALS = require("ndoo.portals") +local GITHUB = require("ndoo.portals.github") +local GITLAB = require("ndoo.portals.gitlab") +local BITBUCKET = require("ndoo.portals.bitbucket") function get_base_repo_url(remote) - local repo_owner = HELPER.get_github_repo_owner(remote) - local repo_name = HELPER.get_github_repo_name(remote) - if (repo_owner == nil or repo_name == nil) then - print("not a github repo") - return nil + local repo_owner = "" + local repo_name = "" + if PORTALS.is_github() then + repo_owner = GITHUB.get_github_repo_owner(remote) + repo_name = GITHUB.get_github_repo_name(remote) + if (repo_owner ~= nil or repo_name ~= nil) then + return GITHUB.base_url .. repo_owner .. "/" .. repo_name + end + elseif PORTALS.is_gitlab() then + repo_owner = GITLAB.get_gitlab_repo_owner(remote) + repo_name = GITLAB.get_gitlab_repo_name(remote) + if (repo_owner ~= nil or repo_name ~= nil) then + return GITLAB.base_url .. repo_owner .. "/" .. repo_name + end + elseif PORTALS.is_bitbucket() then + repo_owner = BITBUCKET.get_bitbucket_repo_owner(remote) + repo_name = BITBUCKET.get_bitbucket_repo_name(remote) + if (repo_owner ~= nil or repo_name ~= nil) then + return BITBUCKET.base_url .. repo_owner .. "/" .. repo_name + end end - return GITHUB.base_url .. repo_owner .. "/" .. repo_name + vim.notify("No supported portal detected", vim.log.levels.ERROR) + return nil end function open_slug(slug) @@ -42,10 +61,22 @@ function open_from_visual_selection(commit) local filename = vim.fn.expand("%") if commit == nil then local branch = HELPER.get_current_git_branch() - show_remote_names_picker_and_open_slug("blob/" .. branch .. "/" .. filename .. "?plain=1#L" .. line_start .. "-L" .. line_end) + if PORTALS.is_github() then + show_remote_names_picker_and_open_slug("blob/" .. branch .. "/" .. filename .. "?plain=1#L" .. line_start .. "-L" .. line_end) + elseif PORTALS.is_gitlab() then + show_remote_names_picker_and_open_slug("blob/" .. branch .. "/" .. filename .. "#L" .. line_start .. "-" .. line_end) + elseif PORTALS.is_bitbucket() then + show_remote_names_picker_and_open_slug("src/" .. branch .. "/" .. filename .. "#lines-" .. line_start .. ":" .. line_end) + end else local commit_hash = HELPER.get_current_git_commit_hash() - show_remote_names_picker_and_open_slug("blob/" .. commit_hash .. "/" .. filename .. "?plain=1#L" .. line_start .. "-L" .. line_end) + if PORTALS.is_github() then + show_remote_names_picker_and_open_slug("blob/" .. commit_hash .. "/" .. filename .. "?plain=1#L" .. line_start .. "-L" .. line_end) + elseif PORTALS.is_gitlab() then + show_remote_names_picker_and_open_slug("blob/" .. commit_hash .. "/" .. filename .. "#L" .. line_start .. "-" .. line_end) + elseif PORTALS.is_bitbucket() then + show_remote_names_picker_and_open_slug("src/" .. commit_hash .. "/" .. filename .. "#lines-" .. line_start .. ":" .. line_end) + end end end @@ -54,10 +85,22 @@ function open_from_normal_mode(commit) local filename = vim.fn.expand("%") if commit == nil then local branch = HELPER.get_current_git_branch() - show_remote_names_picker_and_open_slug("blob/" .. branch .. "/" .. filename .. "?plain=1#L" .. line_number) + if PORTALS.is_github() then + show_remote_names_picker_and_open_slug("blob/" .. branch .. "/" .. filename .. "?plain=1#L" .. line_number) + elseif PORTALS.is_gitlab() then + show_remote_names_picker_and_open_slug("blob/" .. branch .. "/" .. filename .. "#L" .. line_number) + elseif PORTALS.is_bitbucket() then + show_remote_names_picker_and_open_slug("src/" .. branch .. "/" .. filename .. "#lines-" .. line_number) + end else local commit_hash = HELPER.get_current_git_commit_hash() - show_remote_names_picker_and_open_slug("blob/" .. commit_hash .. "/" .. filename .. "?plain=1#L" .. line_number) + if PORTALS.is_github() then + show_remote_names_picker_and_open_slug("blob/" .. commit_hash .. "/" .. filename .. "?plain=1#L" .. line_number) + elseif PORTALS.is_gitlab() then + show_remote_names_picker_and_open_slug("blob/" .. commit_hash .. "/" .. filename .. "#L" .. line_number) + elseif PORTALS.is_bitbucket() then + show_remote_names_picker_and_open_slug("src/" .. commit_hash .. "/" .. filename .. "#lines-" .. line_number) + end end end @@ -92,37 +135,98 @@ function M.repo() end function M.pulls() - HELPER.show_github_pull_picker(function(pull_number) - if (pull_number == nil) then - print("no pull selected") - return - end - open_slug("pull/" .. pull_number) - end) + if PORTALS.is_github() then + GITHUB.show_github_pull_picker(function(pull_number) + if (pull_number == nil) then + print("no pull selected") + return + end + open_slug("pull/" .. pull_number) + end) + elseif PORTALS.is_gitlab() then + GITLAB.show_gitlab_pull_picker(function(pull_number) + if (pull_number == nil) then + print("no pull selected") + return + end + open_slug("merge_requests/" .. pull_number) + end) + elseif PORTALS.is_bitbucket() then + BITBUCKET.show_bitbucket_pull_picker(function(pull_number) + if (pull_number == nil) then + print("no pull selected") + return + end + open_slug("pull-requests/" .. pull_number) + end) + end + end function M.issues() - HELPER.show_github_issues_picker(function(issue_number) - if (issue_number == nil) then - print("no issue selected") - return - end - open_slug("issues/" .. issue_number) - end) + if PORTALS.is_github() then + GITHUB.show_github_issues_picker(function(issue_number) + if (issue_number == nil) then + print("no issue selected") + return + end + open_slug("issues/" .. issue_number) + end) + elseif PORTALS.is_gitlab() then + GITLAB.show_gitlab_issues_picker(function(issue_number) + if (issue_number == nil) then + print("no issue selected") + return + end + open_slug("issues/" .. issue_number) + end) + elseif PORTALS.is_bitbucket() then + BITBUCKET.show_bitbucket_issues_picker(function(issue_number) + if (issue_number == nil) then + print("no issue selected") + return + end + open_slug("issues/" .. issue_number) + end) + end end function M.labels() - HELPER.show_github_labels_picker(function(label_url) - if (label_url == nil) then - print("no label selected") - return - end - HELPER.open_url_in_browser(label_url) - end) + if PORTALS.is_github() then + GITHUB.show_github_labels_picker(function(label_url) + if (label_url == nil) then + print("no label selected") + return + end + HELPER.open_url_in_browser(label_url) + end) + elseif PORTALS.is_gitlab() then + GITLAB.show_gitlab_labels_picker(function(label_url) + if (label_url == nil) then + print("no label selected") + return + end + HELPER.open_url_in_browser(label_url) + end) + elseif PORTALS.is_bitbucket() then + BITBUCKET.show_bitbucket_labels_picker(function(label_url) + if (label_url == nil) then + print("no label selected") + return + end + HELPER.open_url_in_browser(label_url) + end) + end end function M.pipelines() - show_remote_names_picker_and_open_slug("actions") + if PORTALS.is_github() then + show_remote_names_picker_and_open_slug("actions") + elseif PORTALS.is_gitlab() then + show_remote_names_picker_and_open_slug("pipelines") + elseif PORTALS.is_bitbucket() then + show_remote_names_picker_and_open_slug("pipelines") + end end function M.commit() diff --git a/lua/ndoo/portals/bitbucket.lua b/lua/ndoo/portals/bitbucket.lua new file mode 100644 index 0000000..278c653 --- /dev/null +++ b/lua/ndoo/portals/bitbucket.lua @@ -0,0 +1,114 @@ +local CONFIG = require("ndoo.config") +local pickers = require("ndoo.helper.pickers") +local JSON_CONFIG = CONFIG.get_config_json() +local USERNAME = JSON_CONFIG.bitbucket_username +local APP_PASSWORD = JSON_CONFIG.bitbucket_app_password +local BASE64_CREDS = vim.base64.encode(USERNAME .. ":" .. APP_PASSWORD) + +local M = {} + +M.base_url = "https://bitbucket.org/" +M.API_BASE_URL = "https://api.bitbucket.org" + +local function get_data(slug) + local repo_owner = M.get_bitbucket_repo_owner() + local repo_name = M.get_bitbucket_repo_name() + local curl_cmd = "curl -s -X GET -H 'Authorization: Basic " .. BASE64_CREDS .. "' " .. M.API_BASE_URL .. "/2.0/repositories/" .. repo_owner .. "/" .. repo_name .. "/" .. slug + local jsonstr = vim.fn.system(curl_cmd) + local data = vim.fn.json_decode(jsonstr) + return data +end + +function M.show_bitbucket_labels_picker(cb_func) + vim.notify("Bitbucket does not support labels", vim.log.levels.ERROR) +end + +function M.show_bitbucket_pull_picker(cb_func) + local pulls = get_data("pullrequests") + if pulls.error ~= nil then + vim.notify(pulls.error.message, vim.log.levels.ERROR) + return + end + pickers.generic_table_picker({ + prompt_title = "Pick a pull", + results = pulls.values, + entry_maker_value_key = "links.html.href", + entry_maker_display_key = "title", + entry_maker_ordinal_key = "title", + preview = true, + previewer_value_key = "description", + cb_func = cb_func, + }) +end + +function M.show_bitbucket_issues_picker(cb_func) + local issues = get_data("issues") + if issues.error ~= nil then + vim.notify(issues.error.message, vim.log.levels.ERROR) + return + end + pickers.generic_table_picker({ + prompt_title = "Pick an issue", + results = issues.values, + entry_maker_value_key = "links.html.href", + entry_maker_display_key = "title", + entry_maker_ordinal_key = "title", + preview = true, + previewer_value_key = "content.raw", + cb_func = cb_func, + }) +end + +function M.get_bitbucket_remote_url(remote) + if remote == nil then + remote = "origin" + end + local url = vim.fn.systemlist("git remote get-url " .. remote)[1] + if url == "" then + return nil + end + return url +end + +function M.get_bitbucket_repo_protocol() + local url = M.get_bitbucket_remote_url() + if url:match("^git@") then + return "ssh" + end + if url:match("^https://") then + return "https" + end + return nil +end + +function M.get_bitbucket_repo_name(remote) + local url = M.get_bitbucket_remote_url(remote) + if url == nil then + return nil + end + local repo_name = url:match("^.+/(.+)$") + if repo_name == nil then + return nil + end + repo_name = repo_name:gsub("%.git$", "") + return repo_name +end + +function M.get_bitbucket_repo_owner(remote) + local url = M.get_bitbucket_remote_url(remote) + if url == nil then + return nil + end + local repo_owner = nil + local repo_protocol = M.get_bitbucket_repo_protocol(remote) + if repo_protocol == "ssh" then + repo_owner = url:match("^.+:(.+)/.+$") + end + if repo_protocol == "https" then + repo_owner = url:match("^.+/(.+)/.+$") + end + return repo_owner +end + +return M + diff --git a/lua/ndoo/portals/github.lua b/lua/ndoo/portals/github.lua new file mode 100644 index 0000000..ca979d6 --- /dev/null +++ b/lua/ndoo/portals/github.lua @@ -0,0 +1,105 @@ +local M = {} +local pickers = require("ndoo.helper.pickers") + +M.base_url = "https://github.com/" + +function M.show_github_labels_picker(cb_func) + local jsonstr = vim.fn.system("gh label list --json name,description,url -L 30") + local pulls = vim.fn.json_decode(jsonstr) + + pickers.generic_table_picker({ + prompt_title = "Pick a label", + dropdown = true, + results = pulls, + entry_maker_value_key = "url", + entry_maker_display_key = "name", + entry_maker_ordinal_key = "name", + cb_func = cb_func, + }) +end + +function M.show_github_pull_picker(cb_func) + local jsonstr = vim.fn.system("gh pr list --json number,title,body,updatedAt -L 2000") + local pulls = vim.fn.json_decode(jsonstr) + + pickers.generic_table_picker({ + prompt_title = "Pick a pull", + results = pulls, + entry_maker_value_key = "number", + entry_maker_display_key = "title", + entry_maker_ordinal_key = "title", + preview = true, + previewer_value_key = "body", + cb_func = cb_func, + }) +end + +function M.show_github_issues_picker(cb_func) + local jsonstr = vim.fn.system("gh issue list --json number,title,body,updatedAt -L 2000") + local issues = vim.fn.json_decode(jsonstr) + + pickers.generic_table_picker({ + prompt_title = "Pick an issue", + results = issues, + entry_maker_value_key = "number", + entry_maker_display_key = "title", + entry_maker_ordinal_key = "title", + preview = true, + previewer_value_key = "body", + cb_func = cb_func, + }) +end + +function M.get_github_remote_url(remote) + if remote == nil then + remote = "origin" + end + local url = vim.fn.systemlist("git remote get-url " .. remote)[1] + if url == "" then + return nil + end + return url +end + +function M.get_github_repo_protocol() + local url = M.get_github_remote_url() + if url:match("^git@") then + return "ssh" + end + if url:match("^https://") then + return "https" + end + return nil +end + +function M.get_github_repo_name(remote) + local url = M.get_github_remote_url(remote) + if url == nil then + return nil + end + local repo_name = url:match("^.+/(.+)$") + if repo_name == nil then + return nil + end + repo_name = repo_name:gsub("%.git$", "") + return repo_name +end + +function M.get_github_repo_owner(remote) + local url = M.get_github_remote_url(remote) + if url == nil then + return nil + end + local repo_owner = nil + local repo_protocol = M.get_github_repo_protocol(remote) + if repo_protocol == "ssh" then + repo_owner = url:match("^.+:(.+)/.+$") + end + if repo_protocol == "https" then + repo_owner = url:match("^.+/(.+)/.+$") + end + return repo_owner +end + +return M + diff --git a/lua/ndoo/portals/gitlab.lua b/lua/ndoo/portals/gitlab.lua new file mode 100644 index 0000000..d038a7b --- /dev/null +++ b/lua/ndoo/portals/gitlab.lua @@ -0,0 +1,6 @@ +local M = {} + +M.base_url = "https://gitlab.com/" + +return M + diff --git a/lua/ndoo/portals/init.lua b/lua/ndoo/portals/init.lua new file mode 100644 index 0000000..9df19f6 --- /dev/null +++ b/lua/ndoo/portals/init.lua @@ -0,0 +1,39 @@ +local M = {} + +local function get_git_remote_url(remote) + if remote == nil then + remote = "origin" + end + local url = vim.fn.systemlist("git remote get-url " .. remote)[1] + if url == "" then + return nil + end + return url +end + +M.is_bitbucket = function() + local remote_url = get_git_remote_url() + if remote_url == nil then + return false + end + return remote_url:match("bitbucket.org") ~= nil +end + +M.is_gitlab = function() + local remote_url = get_git_remote_url() + if remote_url == nil then + return false + end + return remote_url:match("gitlab.com") ~= nil +end + +M.is_github = function() + local remote_url = get_git_remote_url() + if remote_url == nil then + return false + end + return remote_url:match("github.com") ~= nil +end + + +return M