Skip to content

Commit

Permalink
chore: Pass namespaces around less, make help and spinner highlight c…
Browse files Browse the repository at this point in the history
…onfigurable

- As pointed out in recent PRs with highlight changes, create_namespace
do not rly needs to be stored so we do not need to pass them around
everywhere. This simplifies the code a bit
- To make the highlights consistent after recent highlight changes, make
the remaining highlights configurable as well

Signed-off-by: Tomas Slusny <[email protected]>
  • Loading branch information
deathbeam committed May 27, 2024
1 parent b6e052a commit 7df47a5
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 90 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ Also see [here](/lua/CopilotChat/config.lua):
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
Expand Down
12 changes: 3 additions & 9 deletions lua/CopilotChat/chat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ local Spinner = require('CopilotChat.spinner')
local utils = require('CopilotChat.utils')
local is_stable = utils.is_stable
local class = utils.class
local show_virt_line = utils.show_virt_line

function CopilotChatFoldExpr(lnum, separator)
local line = vim.fn.getline(lnum)
Expand All @@ -32,8 +31,7 @@ function CopilotChatFoldExpr(lnum, separator)
return '='
end

local Chat = class(function(self, mark_ns, help, on_buf_create)
self.mark_ns = mark_ns
local Chat = class(function(self, help, on_buf_create)
self.header_ns = vim.api.nvim_create_namespace('copilot-chat-headers')
self.help = help
self.on_buf_create = on_buf_create
Expand All @@ -54,7 +52,7 @@ local Chat = class(function(self, mark_ns, help, on_buf_create)
end

if not self.spinner then
self.spinner = Spinner(bufnr, mark_ns, 'copilot-chat')
self.spinner = Spinner(bufnr)
else
self.spinner.bufnr = bufnr
end
Expand Down Expand Up @@ -254,12 +252,8 @@ function Chat:finish(msg)
else
msg = self.help
end
msg = vim.trim(msg)

if msg and msg ~= '' then
local line = vim.api.nvim_buf_line_count(self.bufnr) - 2
show_virt_line(msg, math.max(0, line - 1), self.bufnr, self.mark_ns)
end
self:show_help(msg, -2)
end

return Chat
88 changes: 39 additions & 49 deletions lua/CopilotChat/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -275,32 +275,32 @@ function M.prompts(skip_system)
return prompts_to_use
end

local selection_ns = nil ---@type number

--- Highlights the selection in the source buffer.
---@param clear? boolean
function M.highlight_selection(clear)
local selection_ns = vim.api.nvim_create_namespace('copilot-chat-selection')
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
vim.api.nvim_buf_clear_namespace(buf, selection_ns, 0, -1)
end
if clear then
return
end
local selection = get_selection()
if selection then
vim.api.nvim_buf_set_extmark(
state.source.bufnr,
selection_ns,
selection.start_row - 1,
selection.start_col - 1,
{
hl_group = 'CopilotChatSelection',
end_row = selection.end_row - 1,
end_col = selection.end_col,
strict = false,
}
)
if not selection then
return
end
vim.api.nvim_buf_set_extmark(
state.source.bufnr,
selection_ns,
selection.start_row - 1,
selection.start_col - 1,
{
hl_group = 'CopilotChatSelection',
end_row = selection.end_row - 1,
end_col = selection.end_col,
strict = false,
}
)
end

--- Open the chat window.
Expand Down Expand Up @@ -606,21 +606,23 @@ function M.setup(config)
state.copilot = Copilot(M.config.proxy, M.config.allow_insecure)
M.debug(M.config.debug)

selection_ns = vim.api.nvim_create_namespace('copilot-chat-selection')
local mark_ns = vim.api.nvim_create_namespace('copilot-chat-marks')
local hl_ns = vim.api.nvim_create_namespace('copilot-chat-highlights')
vim.api.nvim_set_hl(hl_ns, '@diff.plus', { bg = blend_color_with_neovim_bg('DiffAdd', 20) })
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, 'CopilotChatSpinner', { link = 'CursorColumn', default = true })
vim.api.nvim_set_hl(0, 'CopilotChatHelp', { link = 'DiagnosticInfo', default = true })
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,
})
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
Expand All @@ -637,7 +639,7 @@ function M.setup(config)
if state.diff then
state.diff:delete()
end
state.diff = Overlay('copilot-diff', mark_ns, hl_ns, diff_help, function(bufnr)
state.diff = Overlay('copilot-diff', hl_ns, diff_help, function(bufnr)
map_key(M.config.mappings.close, bufnr, function()
state.diff:restore(state.chat.winnr, state.chat.bufnr)
end)
Expand Down Expand Up @@ -670,32 +672,20 @@ function M.setup(config)
if state.system_prompt then
state.system_prompt:delete()
end
state.system_prompt = Overlay(
'copilot-system-prompt',
mark_ns,
hl_ns,
overlay_help,
function(bufnr)
map_key(M.config.mappings.close, bufnr, function()
state.system_prompt:restore(state.chat.winnr, state.chat.bufnr)
end)
end
)
state.system_prompt = Overlay('copilot-system-prompt', hl_ns, overlay_help, function(bufnr)
map_key(M.config.mappings.close, bufnr, function()
state.system_prompt:restore(state.chat.winnr, state.chat.bufnr)
end)
end)

if state.user_selection then
state.user_selection:delete()
end
state.user_selection = Overlay(
'copilot-user-selection',
mark_ns,
hl_ns,
overlay_help,
function(bufnr)
map_key(M.config.mappings.close, bufnr, function()
state.user_selection:restore(state.chat.winnr, state.chat.bufnr)
end)
end
)
state.user_selection = Overlay('copilot-user-selection', hl_ns, overlay_help, function(bufnr)
map_key(M.config.mappings.close, bufnr, function()
state.user_selection:restore(state.chat.winnr, state.chat.bufnr)
end)
end)

local chat_help = ''
if M.config.show_help then
Expand All @@ -718,7 +708,7 @@ function M.setup(config)
state.chat:close()
state.chat:delete()
end
state.chat = Chat(mark_ns, chat_help, function(bufnr)
state.chat = Chat(chat_help, function(bufnr)
map_key(M.config.mappings.complete, bufnr, complete)
map_key(M.config.mappings.reset, bufnr, M.reset)
map_key(M.config.mappings.close, bufnr, M.close)
Expand Down
34 changes: 27 additions & 7 deletions lua/CopilotChat/overlay.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
---@field show fun(self: CopilotChat.Overlay, text: string, filetype: string, syntax: string, winnr: number)
---@field restore fun(self: CopilotChat.Overlay, winnr: number, bufnr: number)
---@field delete fun(self: CopilotChat.Overlay)
---@field show_help fun(self: CopilotChat.Overlay, msg: string, offset: number)

local utils = require('CopilotChat.utils')
local class = utils.class
local show_virt_line = utils.show_virt_line

local Overlay = class(function(self, name, mark_ns, hl_ns, help, on_buf_create)
self.mark_ns = mark_ns
local Overlay = class(function(self, name, hl_ns, help, on_buf_create)
self.hl_ns = hl_ns
self.help = help
self.on_buf_create = on_buf_create
Expand Down Expand Up @@ -48,10 +47,8 @@ function Overlay:show(text, filetype, syntax, winnr)
vim.bo[self.bufnr].modifiable = true
vim.api.nvim_buf_set_lines(self.bufnr, 0, -1, false, vim.split(text, '\n'))
vim.bo[self.bufnr].modifiable = false

local line = vim.api.nvim_buf_line_count(self.bufnr) - 1
vim.api.nvim_win_set_cursor(winnr, { line + 1, 0 })
show_virt_line(self.help, math.max(0, line), self.bufnr, self.mark_ns)
self:show_help(self.help, -1)
vim.api.nvim_win_set_cursor(winnr, { vim.api.nvim_buf_line_count(self.bufnr), 0 })

-- Dual mode with treesitter (for diffs for example)
vim.api.nvim_win_set_hl_ns(winnr, self.hl_ns)
Expand All @@ -76,4 +73,27 @@ function Overlay:delete()
end
end

function Overlay:show_help(msg, offset)
if not msg then
return
end

msg = vim.trim(msg)
if msg == '' then
return
end

self:validate()
local help_ns = vim.api.nvim_create_namespace('copilot-chat-help')
local line = vim.api.nvim_buf_line_count(self.bufnr) + offset
vim.api.nvim_buf_set_extmark(self.bufnr, help_ns, math.max(0, line - 1), 0, {
id = help_ns,
hl_mode = 'combine',
priority = 100,
virt_lines = vim.tbl_map(function(t)
return { { t, 'CopilotChatHelp' } }
end, vim.split(msg, '\n')),
})
end

return Overlay
7 changes: 3 additions & 4 deletions lua/CopilotChat/spinner.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ local spinner_frames = {
'',
}

local Spinner = class(function(self, bufnr, ns, title)
self.ns = ns
local Spinner = class(function(self, bufnr)
self.ns = vim.api.nvim_create_namespace('copilot-chat-help')
self.bufnr = bufnr
self.title = title
self.timer = nil
self.index = 1
end)
Expand Down Expand Up @@ -57,7 +56,7 @@ function Spinner:start()
hl_mode = 'combine',
priority = 100,
virt_text = vim.tbl_map(function(t)
return { t, 'CursorColumn' }
return { t, 'CopilotChatSpinner' }
end, vim.split(spinner_frames[self.index], '\n')),
}
)
Expand Down
20 changes: 0 additions & 20 deletions lua/CopilotChat/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,26 +62,6 @@ function M.join(on_done, fns)
end
end

--- Show a virtual line
---@param text string The text to show
---@param line number The line number
---@param bufnr number The buffer number
---@param mark_ns number The namespace
function M.show_virt_line(text, line, bufnr, mark_ns)
if not vim.api.nvim_buf_is_valid(bufnr) then
return
end

vim.api.nvim_buf_set_extmark(bufnr, mark_ns, math.max(0, line), 0, {
id = mark_ns,
hl_mode = 'combine',
priority = 100,
virt_lines = vim.tbl_map(function(t)
return { { t, 'DiagnosticInfo' } }
end, vim.split(text, '\n')),
})
end

--- Writes text to a temporary file and returns path
---@param text string The text to write
---@return string?
Expand Down

0 comments on commit 7df47a5

Please sign in to comment.