From f4c9ccf630c29308c38de63696e1f72beb6a4dd8 Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Fri, 27 Dec 2024 23:38:21 +0100 Subject: [PATCH] Add ability do delete records --- README.md | 7 ++ lua/telescope/_extensions/knot.lua | 118 +++++++++++++++++++---------- 2 files changed, 84 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 17db793..0645cf2 100644 --- a/README.md +++ b/README.md @@ -23,15 +23,22 @@ If knotctl works for you in your terminal, it should work in this plugin as well This plugin provides a Telescope picker for viewing and editing DNS records. You can summon it with: ```vim :Telescope knot update + ``` You can also add new records with: ```vim :Telescope knot add ``` +or delete records with: +```vim +:Telescope knot delete +``` + or add a mapping: ```vim nnoremap ka :Telescope knot add +nnoremap kd :Telescope knot delete nnoremap ku :Telescope knot update ``` You can edit the record and when saving it with `:w` you will be asked to confirm. You can quit the buffer with `:q` or `q` to discard changes. diff --git a/lua/telescope/_extensions/knot.lua b/lua/telescope/_extensions/knot.lua index 5e0b6e5..5e1356b 100644 --- a/lua/telescope/_extensions/knot.lua +++ b/lua/telescope/_extensions/knot.lua @@ -14,6 +14,27 @@ local _get_name = function(record) return name end +local _get_records_and_entries = function() + local results = vim.json.decode(vim.fn.system("knotctl --json list")) + local records = {} + + for _, zone in ipairs(results) do + for _, record in ipairs(zone.records) do + if record then + record.zone = zone.name + table.insert(records, record) + end + end + end + local entries = vim.tbl_map( + function(record) + return _get_name(record) + end, + records + ) + return records, entries +end + local _filter_records = function(rec, records) local r = {} local record_name = rec.value @@ -27,7 +48,16 @@ local _filter_records = function(rec, records) return r end - +local _parse_record = function(rec) + local record = {} + for _, v in ipairs(rec) do + if v ~= nil and v ~= "" then + local key = v:match("%w+"):lower() + record[key] = v:gsub("%w+%:%s", "") + end + end + return record +end local M = {} M.add = function(_) @@ -51,18 +81,12 @@ M.add = function(_) buffer = buffer, callback = function(_) local new = vim.api.nvim_buf_get_lines(buffer, 0, -1, false) - local record = {} - for _, v in ipairs(new) do - if v ~= nil and v ~= "" then - local key = v:match("%w+"):lower() - record[key] = v:gsub("%w+%:%s", "") - end - end - local command = "knotctl add -z" .. record.zone .. - " -t" .. record.ttl .. - " -n" .. record.name .. - " -r" .. record.rtype .. - " -d" .. record.data + local record = _parse_record(new) + local command = "knotctl add -z " .. record.zone .. + " -t " .. record.ttl .. + " -n " .. record.name .. + " -r " .. record.rtype .. + " -d " .. record.data local choice = vim.fn.confirm("Create record?", "&Yes\n&No", 2) if choice == 1 then log.info(vim.fn.system(command)) @@ -70,24 +94,41 @@ M.add = function(_) end }) end -M.update = function(opts) - local results = vim.json.decode(vim.fn.system("knotctl --json list")) - local records = {} - - for _, zone in ipairs(results) do - for _, record in ipairs(zone.records) do - if record then - record.zone = zone.name - table.insert(records, record) +M.delete = function(opts) + local records, entries = _get_records_and_entries() + pickers.new(opts, { + dropdown = true, + prompt_title = "Records", + sorter = conf.generic_sorter(opts), + finder = finders.new_table(entries), + previewer = previewers.new_buffer_previewer({ + title = "Record", + define_preview = function(self, entry) + local record = _filter_records(entry, records) + vim.api.nvim_buf_set_lines(self.state.bufnr, 0, 0, false, record) end - end - end - local entries = vim.tbl_map( - function(record) - return _get_name(record) + + }), + attach_mappings = function(prompt_bufnr) + actions.select_default:replace(function() + local entry = action_state.get_selected_entry() + local record = _parse_record(_filter_records(entry, records)) + local choice = vim.fn.confirm("Delete record?", "&Yes\n&No", 2) + if choice == 1 then + local command = "knotctl delete -z " .. record.zone .. + " -n " .. record.name .. + " -r " .. record.rtype .. + " -d " .. record.data + log.info(vim.fn.system(command)) + actions.close(prompt_bufnr) + end + end) + return true end, - records - ) + }):find() +end +M.update = function(opts) + local records, entries = _get_records_and_entries() pickers.new(opts, { dropdown = true, prompt_title = "Records", @@ -126,15 +167,9 @@ M.update = function(opts) callback = function(_) local new = vim.api.nvim_buf_get_lines(buffer, 0, -1, false) if new ~= record then - local cleanold = {} + local cleanold = _parse_record(record) local updated = {} local did_update = false - for _, v in ipairs(record) do - if v ~= nil and v ~= "" then - local key = v:match("%w+"):lower() - cleanold[key] = v:gsub("%w+%:%s", "") - end - end local cleannew = {} for _, v in ipairs(new) do if v ~= nil and v ~= "" then @@ -147,11 +182,11 @@ M.update = function(opts) end end if did_update then - local command = "knotctl update -z" .. cleanold.zone .. - " -t" .. cleanold.ttl .. - " -n" .. cleanold.name .. - " -r" .. cleanold.rtype .. - " -d" .. cleanold.data .. + local command = "knotctl update -z " .. cleanold.zone .. + " -t " .. cleanold.ttl .. + " -n " .. cleanold.name .. + " -r " .. cleanold.rtype .. + " -d " .. cleanold.data .. table.concat(updated, " ") local choice = vim.fn.confirm("Update record?", "&Yes\n&No", 2) if choice == 1 then @@ -169,6 +204,7 @@ end return require('telescope').register_extension({ exports = { add = M.add, + delete = M.delete, update = M.update, }, })