From 442a44176b5f51e7ea57e126f29fd49ab1fc0a33 Mon Sep 17 00:00:00 2001 From: Tibor Schmidt Date: Fri, 30 Aug 2024 17:22:38 +0200 Subject: [PATCH] chore: better behavior of ChatHelp toggle --- after/ftplugin/gpchat.lua | 11 ++++-- lua/gp/init.lua | 83 ++++++++++++++++++++++++--------------- 2 files changed, 59 insertions(+), 35 deletions(-) diff --git a/after/ftplugin/gpchat.lua b/after/ftplugin/gpchat.lua index 20699e62..3e28d9fe 100644 --- a/after/ftplugin/gpchat.lua +++ b/after/ftplugin/gpchat.lua @@ -117,16 +117,21 @@ vim.api.nvim_create_autocmd({ "User" }, { M.logger.debug("gpchat: refreshing buffer " .. buf .. " " .. vim.json.encode(event)) - M.chat_help(buf) + M.chat_header(buf) vim.api.nvim_buf_clear_namespace(buf, ns_id, 0, -1) + local msg = "Current Agent: [" .. M._state.chat_agent .. "]" + if not M._state.show_chat_help then + msg = "Toggle help: " .. M.config.chat_shortcut_help.shortcut .. " | " .. msg + end + vim.api.nvim_buf_set_extmark(buf, ns_id, 0, 0, { strict = false, - right_gravity = true, + right_gravity = false, virt_text_pos = "right_align", virt_text = { - { "Current Agent: [" .. M._state.chat_agent .. "]", "DiagnosticHint" }, + { msg, "DiagnosticHint" }, }, hl_mode = "combine", }) diff --git a/lua/gp/init.lua b/lua/gp/init.lua index 71be5e0f..b175c73e 100644 --- a/lua/gp/init.lua +++ b/lua/gp/init.lua @@ -250,22 +250,6 @@ M.setup = function(opts) end end - vim.filetype.add({ - extension = { - md = function(path, buf) - M.logger.debug("filetype markdown: " .. path .. " buf: " .. buf) - if not M.not_chat(buf, path) then - return "markdown.gpchat" - end - - if M.helpers.ends_with(path, ".gp.md") then - return "markdown.gpmd" - end - return "markdown" - end, - }, - }) - vim.api.nvim_create_autocmd("BufEnter", { pattern = "*.md", callback = function(ev) @@ -279,7 +263,7 @@ M.setup = function(opts) vim.bo[buf].filetype = "markdown.gpmd" end vim.cmd("doautocmd User GpRefresh") - end, 3) + end, 1) end, }) @@ -731,8 +715,11 @@ M.new_chat = function(params, toggle, system_prompt, agent) -- strip leading and trailing newlines template = template:gsub("^%s*(.-)%s*$", "%1") .. "\n" + local lines = vim.split(template, "\n") + lines = M.chat_header_lines(lines) + -- create chat file - vim.fn.writefile(vim.split(template, "\n"), filename) + vim.fn.writefile(lines, filename) local target = M.resolve_buf_target(params) local buf = M.open_buf(filename, target, M._toggle_kind.chat, toggle) @@ -1063,23 +1050,23 @@ M.chat_respond = function(params) ) end ----@param buf number -M.chat_help = function(buf) - local file_name = vim.api.nvim_buf_get_name(buf) - M.logger.debug("ChatHelp: buffer: " .. buf .. " file: " .. file_name) - local reason = M.not_chat(buf, file_name) - if reason then - M.logger.debug("File " .. vim.inspect(file_name) .. " does not look like a chat file: " .. vim.inspect(reason)) - return - end - - local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false) +---@param lines table # array of lines to process +---@return table # updated array of lines +---@return number # original header end +---@return number # new header end +M.chat_header_lines = function(lines) local _, _, header_end, comments = M.helpers.parse_headers(lines) if header_end == nil then M.logger.error("Error while parsing headers: --- not found. Check your chat template.") - return + return lines, 0, 0 + end + + if header_end + 1 >= #lines then + return lines, 0, 0 end + local header_lines = table.concat(vim.list_slice(lines, 0, header_end + 1), "\n") + local help_template = M.render.template(M.defaults.chat_help, { ["{{user_prefix}}"] = M.config.chat_user_prefix, ["{{respond_shortcut}}"] = M.config.chat_shortcut_respond.shortcut, @@ -1105,16 +1092,48 @@ M.chat_help = function(buf) end end + local new_header_end = header_end + if M._state.show_chat_help and insert_help then - vim.api.nvim_buf_set_lines(buf, header_end, header_end, false, help_lines) + for i = #help_lines, 1, -1 do + table.insert(lines, new_header_end + 1, help_lines[i]) + end + new_header_end = new_header_end + #help_lines elseif not M._state.show_chat_help and not insert_help then table.sort(drop_lines, function(a, b) return a > b end) for _, index in ipairs(drop_lines) do - vim.api.nvim_buf_set_lines(buf, index, index + 1, false, {}) + table.remove(lines, index + 1) + end + new_header_end = new_header_end - #drop_lines + end + + local j = 1 + while j <= new_header_end do + if lines[j]:match("^%s*$") then + table.remove(lines, j) + new_header_end = new_header_end - 1 + else + j = j + 1 end end + + return lines, header_end, new_header_end +end + +---@param buf number +M.chat_header = function(buf) + local file_name = vim.api.nvim_buf_get_name(buf) + M.logger.debug("ChatHelp: buffer: " .. buf .. " file: " .. file_name) + local reason = M.not_chat(buf, file_name) + if reason then + M.logger.debug("File " .. vim.inspect(file_name) .. " does not look like a chat file: " .. vim.inspect(reason)) + return + end + + local lines, old_header_end, header_end = M.chat_header_lines(vim.api.nvim_buf_get_lines(buf, 0, -1, false)) + vim.api.nvim_buf_set_lines(buf, 0, old_header_end + 1, false, vim.list_slice(lines, 0, header_end + 1)) end M.cmd.ChatHelp = function()