Skip to content

Commit

Permalink
refactor: improve diff handling implementation
Browse files Browse the repository at this point in the history
Extract diff handling into separate class to reduce code duplication and improve
maintainability. Add custom highlighting namespace in diff class and remove
redundant code from overlay class. Add utility function for finding lines
between patterns. Improve diff accepting/showing logic with proper line number
handling.

Move highlighting setup into dedicated diff class and make overlay class more
focused. Add example for code snippet markdown links in prompts to improve
clarity.

Signed-off-by: Tomas Slusny <[email protected]>
  • Loading branch information
deathbeam committed Nov 18, 2024
1 parent ff17f92 commit d36b868
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 195 deletions.
7 changes: 4 additions & 3 deletions lua/CopilotChat/chat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ end

local Chat = class(function(self, help, on_buf_create)
self.header_ns = vim.api.nvim_create_namespace('copilot-chat-headers')
self.name = 'copilot-chat'
self.help = help
self.on_buf_create = on_buf_create
self.bufnr = nil
Expand All @@ -43,12 +44,12 @@ local Chat = class(function(self, help, on_buf_create)
self.highlight_headers = true
self.layout = nil

vim.treesitter.language.register('markdown', 'copilot-chat')
vim.treesitter.language.register('markdown', self.name)

self.buf_create = function()
local bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(bufnr, 'copilot-chat')
vim.bo[bufnr].filetype = 'copilot-chat'
vim.api.nvim_buf_set_name(bufnr, self.name)
vim.bo[bufnr].filetype = self.name
vim.bo[bufnr].syntax = 'markdown'
vim.bo[bufnr].textwidth = 0
local ok, parser = pcall(vim.treesitter.get_parser, bufnr, 'markdown')
Expand Down
105 changes: 105 additions & 0 deletions lua/CopilotChat/diff.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---@class CopilotChat.Diff
---@field bufnr number
---@field show fun(self: CopilotChat.Diff, change: string, reference: string, start_line: number?, end_line: number?, filetype: string, winnr: number)
---@field restore fun(self: CopilotChat.Diff, winnr: number, bufnr: number)
---@field delete fun(self: CopilotChat.Diff)
---@field get_diff fun(self: CopilotChat.Diff): string, string, number?, number?

local Overlay = require('CopilotChat.overlay')
local utils = require('CopilotChat.utils')
local class = utils.class

local Diff = class(function(self, help, on_buf_create)
self.hl_ns = vim.api.nvim_create_namespace('copilot-chat-highlights')
vim.api.nvim_set_hl(
self.hl_ns,
'@diff.plus',
{ bg = utils.blend_color_with_neovim_bg('DiffAdd', 20) }
)
vim.api.nvim_set_hl(
self.hl_ns,
'@diff.minus',
{ bg = utils.blend_color_with_neovim_bg('DiffDelete', 20) }
)
vim.api.nvim_set_hl(
self.hl_ns,
'@diff.delta',
{ bg = utils.blend_color_with_neovim_bg('DiffChange', 20) }
)

self.name = 'copilot-diff'
self.help = help
self.on_buf_create = on_buf_create
self.bufnr = nil
self.change = nil
self.reference = nil
self.start_line = nil
self.end_line = nil
self.filetype = nil

self.buf_create = function()
local bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(bufnr, self.name)
vim.bo[bufnr].filetype = self.name
return bufnr
end
end, Overlay)

function Diff:show(change, reference, start_line, end_line, filetype, winnr)
self.change = change
self.reference = reference
self.start_line = start_line
self.end_line = end_line
self.filetype = filetype

self:validate()
vim.api.nvim_win_set_hl_ns(winnr, self.hl_ns)

-- mini.diff integration (unfinished)
-- local diff_found, diff = pcall(require, 'mini.diff')
-- if diff_found then
-- diff.disable(self.bufnr)
-- Overlay.show(self, change, filetype, winnr)
--
-- vim.b[self.bufnr].minidiff_config = {
-- source = {
-- name = self.name,
-- attach = function(bufnr)
-- diff.set_ref_text(bufnr, reference)
-- diff.toggle_overlay(bufnr)
-- end,
-- },
-- }
--
-- diff.enable(self.bufnr)
-- return
-- end

Overlay.show(
self,
tostring(vim.diff(reference, change, {
result_type = 'unified',
ignore_blank_lines = true,
ignore_whitespace = true,
ignore_whitespace_change = true,
ignore_whitespace_change_at_eol = true,
ignore_cr_at_eol = true,
algorithm = 'myers',
ctxlen = #reference,
})),
filetype,
winnr,
'diff'
)
end

function Diff:restore(winnr, bufnr)
Overlay.restore(self, winnr, bufnr)
vim.api.nvim_win_set_hl_ns(winnr, 0)
end

function Diff:get_diff()
return self.change, self.reference, self.start_line, self.end_line, self.filetype
end

return Diff
Loading

0 comments on commit d36b868

Please sign in to comment.