local action_state = require('telescope.actions.state') local actions = require('telescope.actions') local conf = require("telescope.config").values local finders = require("telescope.finders") local pickers = require("telescope.pickers") local previewers = require("telescope.previewers") local log = require('plenary.log').new { plugin = 'telescope_knot', level = 'info', } local _get_name = function(record) local name = record.name .. " (" .. record.rtype .. "): " .. record.data return name end local _filter_records = function(rec, records) local r = {} local record_name = rec.value for _, record in ipairs(records) do local name = _get_name(record) if name == record_name then r = { "ZONE: " .. record.zone, "RTYPE: " .. record.rtype, "NAME: " .. record.name, "DATA: " .. record.data, "TTL: " .. record.ttl, "URL: " .. record.url } end end return r end local telescope_knot = {} telescope_knot.zones = 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) end end end local entries = vim.tbl_map( function(record) return _get_name(record) end, records ) 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 }), attach_mappings = function(prompt_bufnr) actions.select_default:replace(function() local entry = action_state.get_selected_entry() local record = _filter_records(entry, records) actions.close(prompt_bufnr) local buffer = vim.api.nvim_create_buf(false, true) vim.api.nvim_buf_set_lines(buffer, 0, 0, false, record) local width = vim.api.nvim_win_get_width(0) local height = vim.api.nvim_win_get_height(0) - 10 local _ = vim.api.nvim_open_win(buffer, true, { relative = 'win', bufpos = { 0, 0 }, width = width, height = height, border = 'rounded' }) vim.api.nvim_create_autocmd({ "BufWinLeave" }, { buffer = buffer, callback = function(_) local new = vim.api.nvim_buf_get_lines(buffer, 0, -1, false) if new ~= record then local cleanold = {} local changed = {} 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 local key = v:match("%w+"):lower() cleannew[key] = v:gsub("%w+%:%s", "") if cleanold[key] ~= cleannew[key] and (key ~= "url" or key ~= "zone") then table.insert(changed, " -a " .. key .. "=" .. cleannew[key]) end end end if changed ~= {} then local command = "knotctl update -z" .. cleanold.zone .. " -t" .. cleanold.ttl .. " -n" .. cleanold.name .. " -r" .. cleanold.rtype .. " -d" .. cleanold.data .. table.concat(changed, " ") log.info(vim.fn.system(command)) end end end }) end) return true end, }):find() end return require('telescope').register_extension({ exports = { telescope_knot = telescope_knot.zones, }, })