Skip to content

Commit b6cfd0d

Browse files
committed
refactor: improve diff handling implementation
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]>
1 parent ff17f92 commit b6cfd0d

File tree

6 files changed

+251
-195
lines changed

6 files changed

+251
-195
lines changed

lua/CopilotChat/chat.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ end
3232

3333
local Chat = class(function(self, help, on_buf_create)
3434
self.header_ns = vim.api.nvim_create_namespace('copilot-chat-headers')
35+
self.name = 'copilot-chat'
3536
self.help = help
3637
self.on_buf_create = on_buf_create
3738
self.bufnr = nil
@@ -43,12 +44,12 @@ local Chat = class(function(self, help, on_buf_create)
4344
self.highlight_headers = true
4445
self.layout = nil
4546

46-
vim.treesitter.language.register('markdown', 'copilot-chat')
47+
vim.treesitter.language.register('markdown', self.name)
4748

4849
self.buf_create = function()
4950
local bufnr = vim.api.nvim_create_buf(false, true)
50-
vim.api.nvim_buf_set_name(bufnr, 'copilot-chat')
51-
vim.bo[bufnr].filetype = 'copilot-chat'
51+
vim.api.nvim_buf_set_name(bufnr, self.name)
52+
vim.bo[bufnr].filetype = self.name
5253
vim.bo[bufnr].syntax = 'markdown'
5354
vim.bo[bufnr].textwidth = 0
5455
local ok, parser = pcall(vim.treesitter.get_parser, bufnr, 'markdown')

lua/CopilotChat/diff.lua

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
---@class CopilotChat.Diff
2+
---@field bufnr number
3+
---@field show fun(self: CopilotChat.Diff, change: string, reference: string, start_line: number?, end_line: number?, filetype: string, winnr: number)
4+
---@field restore fun(self: CopilotChat.Diff, winnr: number, bufnr: number)
5+
---@field delete fun(self: CopilotChat.Diff)
6+
---@field get_diff fun(self: CopilotChat.Diff): string, string, number?, number?
7+
8+
local Overlay = require('CopilotChat.overlay')
9+
local utils = require('CopilotChat.utils')
10+
local class = utils.class
11+
12+
local Diff = class(function(self, help, on_buf_create)
13+
self.hl_ns = vim.api.nvim_create_namespace('copilot-chat-highlights')
14+
vim.api.nvim_set_hl(
15+
self.hl_ns,
16+
'@diff.plus',
17+
{ bg = utils.blend_color_with_neovim_bg('DiffAdd', 20) }
18+
)
19+
vim.api.nvim_set_hl(
20+
self.hl_ns,
21+
'@diff.minus',
22+
{ bg = utils.blend_color_with_neovim_bg('DiffDelete', 20) }
23+
)
24+
vim.api.nvim_set_hl(
25+
self.hl_ns,
26+
'@diff.delta',
27+
{ bg = utils.blend_color_with_neovim_bg('DiffChange', 20) }
28+
)
29+
30+
self.name = 'copilot-diff'
31+
self.help = help
32+
self.on_buf_create = on_buf_create
33+
self.bufnr = nil
34+
self.change = nil
35+
self.reference = nil
36+
self.start_line = nil
37+
self.end_line = nil
38+
self.filetype = nil
39+
40+
self.buf_create = function()
41+
local bufnr = vim.api.nvim_create_buf(false, true)
42+
vim.api.nvim_buf_set_name(bufnr, self.name)
43+
vim.bo[bufnr].filetype = self.name
44+
return bufnr
45+
end
46+
end, Overlay)
47+
48+
function Diff:show(change, reference, start_line, end_line, filetype, winnr)
49+
self.change = change
50+
self.reference = reference
51+
self.start_line = start_line
52+
self.end_line = end_line
53+
self.filetype = filetype
54+
55+
self:validate()
56+
vim.api.nvim_win_set_hl_ns(winnr, self.hl_ns)
57+
58+
-- mini.diff integration (unfinished)
59+
-- local diff_found, diff = pcall(require, 'mini.diff')
60+
-- if diff_found then
61+
-- diff.disable(self.bufnr)
62+
-- Overlay.show(self, change, filetype, winnr)
63+
--
64+
-- vim.b[self.bufnr].minidiff_config = {
65+
-- source = {
66+
-- name = self.name,
67+
-- attach = function(bufnr)
68+
-- diff.set_ref_text(bufnr, reference)
69+
-- diff.toggle_overlay(bufnr)
70+
-- end,
71+
-- },
72+
-- }
73+
--
74+
-- diff.enable(self.bufnr)
75+
-- return
76+
-- end
77+
78+
Overlay.show(
79+
self,
80+
tostring(vim.diff(reference, change, {
81+
result_type = 'unified',
82+
ignore_blank_lines = true,
83+
ignore_whitespace = true,
84+
ignore_whitespace_change = true,
85+
ignore_whitespace_change_at_eol = true,
86+
ignore_cr_at_eol = true,
87+
algorithm = 'myers',
88+
ctxlen = #reference,
89+
})),
90+
filetype,
91+
winnr,
92+
'diff'
93+
)
94+
end
95+
96+
function Diff:restore(winnr, bufnr)
97+
Overlay.restore(self, winnr, bufnr)
98+
vim.api.nvim_win_set_hl_ns(winnr, 0)
99+
end
100+
101+
function Diff:get_diff()
102+
return self.change, self.reference, self.start_line, self.end_line, self.filetype
103+
end
104+
105+
return Diff

0 commit comments

Comments
 (0)