diff --git a/README.md b/README.md index 79edbb1f..e11bc3ba 100644 --- a/README.md +++ b/README.md @@ -360,6 +360,7 @@ If no command is passed, the argument to `Octo` is treated as a URL from where a | | remove [label] | Remove a label | | | create [label] | Create a new label | | | delete [label] | Delete an existing label from repo | +| | edit [label] | Edit name or description of an existing label from repo | | milestone | add [milestone] | Add a milestone to current Issue or PR | | | remove | Remove a milestone from current Issue or PR | | | create [milestone] | Create a new milestone | diff --git a/doc/octo.txt b/doc/octo.txt index 985b434f..31300232 100644 --- a/doc/octo.txt +++ b/doc/octo.txt @@ -124,7 +124,8 @@ See |octo-command-examples| for examples. add [label] Add specified label or from the available label menu. remove [label] Remove the specified label or from the menu. create [label] Create a new label. - delete [label] Delete the specific label or from the available label menu. + delete [label] Delete the specified label or from the available label menu. + edit [label] Edit name or description of a specified label or from the available label menu. :Octo assignee [action] *octo-commands-assignee* diff --git a/lua/octo/commands.lua b/lua/octo/commands.lua index 8ff75917..b42976cb 100644 --- a/lua/octo/commands.lua +++ b/lua/octo/commands.lua @@ -384,6 +384,92 @@ function M.setup() remove = function(label) M.remove_label(label) end, + edit = function(label) + --- Get the description of a label + --- @param search string + --- @return table label_info + local get_label_info = function(opts) + local item = gh.label.list { + json = "name,description", + search = opts.search, + jq = ".[0]", + opts = { + mode = "sync", + }, + } + if item == "" then + return {} + end + + return vim.json.decode(item) + end + + --- Change the name or description of a label + --- @param label string + --- @param kind string + --- @param current_value string + local change_label_info = function(label, kind, current_value) + vim.ui.input({ + prompt = "New " .. kind .. " for " .. label .. ": ", + default = current_value, + }, function(new_value) + if utils.is_blank(new_value) then + new_value = current_value + end + + new_value = vim.fn.trim(new_value) + + if new_value == current_value then + utils.info("No changes made to " .. kind .. " for " .. label) + return + end + + local opts = { label } + opts[kind] = new_value + gh.label.edit(opts) + + utils.info("Updated " .. kind .. " for " .. label .. " to " .. new_value) + end) + end + + local cb = function(name) + local info = get_label_info { + search = name, + } + + if utils.is_blank(info) then + utils.error("Nothing found for " .. name) + return + end + + vim.ui.select( + { "name", "description" }, + { prompt = "Edit name or description of label: " .. info.name }, + function(kind) + if utils.is_blank(kind) then + return + end + + change_label_info(info.name, kind, info[kind]) + end + ) + end + + if utils.is_blank(label) then + picker.labels { + cb = function(labels) + if #labels ~= 1 then + utils.error "Please select a single label" + return + end + + cb(labels[1].name) + end, + } + else + cb(label) + end + end, delete = function(label) local delete_labels = function(labels) for _, label in ipairs(labels) do