forked from CopilotC-Nvim/CopilotChat.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiff.lua
More file actions
114 lines (100 loc) · 3.23 KB
/
Copy pathdiff.lua
File metadata and controls
114 lines (100 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
local Overlay = require('CopilotChat.ui.overlay')
local utils = require('CopilotChat.utils')
local class = utils.class
---@class CopilotChat.ui.Diff.Diff
---@field change string
---@field reference string
---@field filename string
---@field filetype string
---@field start_line number
---@field end_line number
---@field bufnr number?
---@class CopilotChat.ui.Diff : CopilotChat.ui.Overlay
---@field hl_ns number
---@field diff CopilotChat.ui.Diff.Diff?
---@field augroup number
local Diff = class(function(self, help, on_buf_create)
Overlay.init(self, 'copilot-diff', 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('DiffAdd', 20) })
vim.api.nvim_set_hl(self.hl_ns, '@diff.minus', { bg = utils.blend_color('DiffDelete', 20) })
vim.api.nvim_set_hl(self.hl_ns, '@diff.delta', { bg = utils.blend_color('DiffChange', 20) })
self.augroup = vim.api.nvim_create_augroup('CopilotChatDiff', { clear = true })
self.diff = nil
end, Overlay)
---@param diff CopilotChat.ui.Diff.Diff
---@param winnr number
---@param full_diff boolean
function Diff:show(diff, winnr, full_diff)
self.diff = diff
self:validate()
vim.api.nvim_win_set_hl_ns(winnr, self.hl_ns)
if not full_diff then
-- Create unified diff view
Overlay.show(
self,
tostring(vim.diff(diff.reference, diff.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 = #diff.reference,
})),
winnr,
diff.filetype,
'diff'
)
return
end
-- Create modified version by applying the change
local modified = {}
if utils.buf_valid(diff.bufnr) then
modified = vim.api.nvim_buf_get_lines(diff.bufnr, 0, -1, false)
end
local change_lines = vim.split(diff.change, '\n')
-- Replace the lines in the modified content
if #modified > 0 then
local start_idx = diff.start_line - 1
local end_idx = diff.end_line - 1
for _ = start_idx, end_idx do
table.remove(modified, start_idx)
end
for i, line in ipairs(change_lines) do
table.insert(modified, start_idx + i - 1, line)
end
else
modified = change_lines
end
Overlay.show(self, table.concat(modified, '\n'), winnr, diff.filetype)
if utils.buf_valid(diff.bufnr) then
vim.cmd('diffthis')
vim.api.nvim_set_current_win(vim.fn.bufwinid(diff.bufnr))
vim.api.nvim_win_set_cursor(0, { diff.start_line, 0 })
vim.cmd('diffthis')
vim.api.nvim_set_current_win(winnr)
vim.api.nvim_win_set_cursor(winnr, { diff.start_line, 0 })
-- Link diff buffers lifecycle
vim.api.nvim_create_autocmd('BufWipeout', {
group = self.augroup,
buffer = self.bufnr,
callback = function()
vim.cmd('diffoff')
end,
})
end
end
---@param winnr number
---@param bufnr number
function Diff:restore(winnr, bufnr)
vim.cmd('diffoff')
Overlay.restore(self, winnr, bufnr)
vim.api.nvim_win_set_hl_ns(winnr, 0)
end
---@return CopilotChat.ui.Diff.Diff?
function Diff:get_diff()
return self.diff
end
return Diff