diff --git a/lua/CopilotChat/chat.lua b/lua/CopilotChat/chat.lua index 4f7c22a3..7d994b25 100644 --- a/lua/CopilotChat/chat.lua +++ b/lua/CopilotChat/chat.lua @@ -1,6 +1,7 @@ ---@class CopilotChat.Chat ---@field bufnr number ---@field winnr number +---@field separator string ---@field spinner CopilotChat.Spinner ---@field valid fun(self: CopilotChat.Chat) ---@field visible fun(self: CopilotChat.Chat) @@ -33,11 +34,13 @@ end local Chat = class(function(self, mark_ns, help, on_buf_create) self.mark_ns = mark_ns + self.header_ns = vim.api.nvim_create_namespace('copilot-chat-headers') self.help = help self.on_buf_create = on_buf_create self.bufnr = nil self.winnr = nil self.spinner = nil + self.separator = nil self.buf_create = function() local bufnr = vim.api.nvim_create_buf(false, true) @@ -66,6 +69,33 @@ function Chat:visible() and vim.api.nvim_win_get_buf(self.winnr) == self.bufnr end +function Chat:render() + if not self:visible() then + return + end + vim.api.nvim_buf_clear_namespace(self.bufnr, self.header_ns, 0, -1) + local lines = vim.api.nvim_buf_get_lines(self.bufnr, 0, -1, false) + for l, line in ipairs(lines) do + if line:match(self.separator .. '$') then + local sep = vim.fn.strwidth(line) - vim.fn.strwidth(self.separator) + -- separator line + vim.api.nvim_buf_set_extmark(self.bufnr, self.header_ns, l - 1, sep, { + virt_text_win_col = sep, + virt_text = { { string.rep(self.separator, vim.go.columns), 'CopilotChatSeparator' } }, + priority = 100, + strict = false, + }) + -- header hl group + vim.api.nvim_buf_set_extmark(self.bufnr, self.header_ns, l - 1, 0, { + end_col = sep + 1, + hl_group = 'CopilotChatHeader', + priority = 100, + strict = false, + }) + end + end +end + function Chat:active() return vim.api.nvim_get_current_win() == self.winnr end @@ -101,11 +131,13 @@ function Chat:append(str) last_column, vim.split(str, '\n') ) + self:render() end function Chat:clear() self:validate() vim.api.nvim_buf_set_lines(self.bufnr, 0, -1, false, {}) + self:render() end function Chat:open(config) @@ -161,6 +193,8 @@ function Chat:open(config) vim.api.nvim_win_set_buf(self.winnr, self.bufnr) end + self.separator = config.separator + vim.wo[self.winnr].wrap = true vim.wo[self.winnr].linebreak = true vim.wo[self.winnr].cursorline = true @@ -173,6 +207,7 @@ function Chat:open(config) else vim.wo[self.winnr].foldcolumn = '0' end + self:render() end function Chat:close() diff --git a/lua/CopilotChat/config.lua b/lua/CopilotChat/config.lua index 9a1bfccb..c962264e 100644 --- a/lua/CopilotChat/config.lua +++ b/lua/CopilotChat/config.lua @@ -89,7 +89,7 @@ return { question_header = '## User ', -- Header to use for user questions answer_header = '## Copilot ', -- Header to use for AI answers error_header = '## Error ', -- Header to use for errors - separator = '---', -- Separator to use in chat + separator = '───', -- Separator to use in chat show_folds = true, -- Shows folds for sections in chat show_help = true, -- Shows help message as virtual lines when waiting for user input diff --git a/lua/CopilotChat/init.lua b/lua/CopilotChat/init.lua index f5641bd8..5183c55e 100644 --- a/lua/CopilotChat/init.lua +++ b/lua/CopilotChat/init.lua @@ -613,6 +613,14 @@ function M.setup(config) vim.api.nvim_set_hl(hl_ns, '@diff.minus', { bg = blend_color_with_neovim_bg('DiffDelete', 20) }) vim.api.nvim_set_hl(hl_ns, '@diff.delta', { bg = blend_color_with_neovim_bg('DiffChange', 20) }) vim.api.nvim_set_hl(0, 'CopilotChatSelection', { link = 'Visual', default = true }) + vim.api.nvim_set_hl(0, 'CopilotChatHeader', { + link = '@markup.heading.2.markdown', + default = true, + }) + vim.api.nvim_set_hl(0, 'CopilotChatSeparator', { + link = '@punctuation.special.markdown', + default = true, + }) local overlay_help = '' if M.config.mappings.close then