-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoverlay.lua
More file actions
104 lines (91 loc) · 3.87 KB
/
Copy pathoverlay.lua
File metadata and controls
104 lines (91 loc) · 3.87 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
local Overlay = {}
function Overlay:new(events)
local instance = {
_events = events,
_logger = require('diffusion.utils.logger'):child('Overlay'),
chat_buf = nil,
input_buf = nil,
chat_win = nil,
input_win = nil,
layout = nil,
}
setmetatable(instance, { __index = self })
return instance
end
function Overlay:_create_buffers()
if not self.chat_buf or not vim.api.nvim_buf_is_valid(self.chat_buf) then
self.chat_buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_option(self.chat_buf, 'buftype', 'nofile')
vim.api.nvim_buf_set_option(self.chat_buf, 'swapfile', false)
vim.api.nvim_buf_set_name(self.chat_buf, 'Diffusion Output')
end
if not self.input_buf or not vim.api.nvim_buf_is_valid(self.input_buf) then
self.input_buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_option(self.input_buf, 'buftype', 'prompt')
vim.api.nvim_buf_set_option(self.input_buf, 'swapfile', false)
vim.fn.prompt_setprompt(self.input_buf, '› ')
end
end
function Overlay:_open_windows()
local ui = vim.api.nvim_list_uis()[1]
local width = math.floor(ui.width * 0.5)
local height = math.floor(ui.height * 0.4)
local col = math.floor((ui.width - width) / 2)
local row = math.floor(ui.height - height - 2)
-- Chat window (top part)
self.chat_win = vim.api.nvim_open_win(self.chat_buf, false, {
relative = 'editor', width = width, height = height - 3,
row = row, col = col, style = 'minimal', border = 'rounded'
})
vim.api.nvim_win_set_option(self.chat_win, 'wrap', true)
vim.api.nvim_win_set_option(self.chat_win, 'cursorline', false)
-- Input window (bottom line)
self.input_win = vim.api.nvim_open_win(self.input_buf, true, {
relative = 'editor', width = width, height = 1,
row = row + height - 2, col = col, style = 'minimal', border = 'rounded'
})
end
function Overlay:show()
self:_create_buffers()
self:_open_windows()
-- Map <CR> on prompt buffer to send message
vim.keymap.set('n', '<CR>', function()
self:submit_input()
end, { buffer = self.input_buf, nowait = true })
vim.keymap.set('i', '<CR>', function()
self:submit_input()
end, { buffer = self.input_buf, nowait = true })
end
function Overlay:append_output(prefix, text)
if not (self.chat_buf and vim.api.nvim_buf_is_valid(self.chat_buf)) then return end
local lines = vim.split(text or '', '\n', { plain = true })
local prefixed = {}
for _, l in ipairs(lines) do table.insert(prefixed, string.format('%s %s', prefix, l)) end
local last = vim.api.nvim_buf_line_count(self.chat_buf)
vim.api.nvim_buf_set_lines(self.chat_buf, last, last, false, prefixed)
if self.chat_win and vim.api.nvim_win_is_valid(self.chat_win) then
vim.api.nvim_win_set_cursor(self.chat_win, { vim.api.nvim_buf_line_count(self.chat_buf), 0 })
end
end
function Overlay:submit_input()
local line = table.concat(vim.api.nvim_buf_get_lines(self.input_buf, 0, -1, false), '\n')
line = line:gsub('^›%s*', '')
if line == '' then return end
self:append_output('You:', line)
-- Clear prompt buffer
vim.api.nvim_buf_set_lines(self.input_buf, 0, -1, false, { '' })
-- Send to provider
local ok, mod = pcall(require, 'diffusion')
if ok and mod then
mod.send_message(line)
end
end
function Overlay:close()
if self.input_win and vim.api.nvim_win_is_valid(self.input_win) then pcall(vim.api.nvim_win_close, self.input_win, true) end
if self.chat_win and vim.api.nvim_win_is_valid(self.chat_win) then pcall(vim.api.nvim_win_close, self.chat_win, true) end
self.input_win, self.chat_win = nil, nil
if self.input_buf and vim.api.nvim_buf_is_valid(self.input_buf) then pcall(vim.api.nvim_buf_delete, self.input_buf, { force = true }) end
if self.chat_buf and vim.api.nvim_buf_is_valid(self.chat_buf) then pcall(vim.api.nvim_buf_delete, self.chat_buf, { force = true }) end
self.input_buf, self.chat_buf = nil, nil
end
return Overlay