Skip to content

Commit cd1b5f1

Browse files
committed
feat: ftplugin for chat files
1 parent 3e90e3d commit cd1b5f1

File tree

2 files changed

+123
-148
lines changed

2 files changed

+123
-148
lines changed

after/ftplugin/gpchat.lua

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
local M = require("gp")
2+
3+
M.logger.debug("gpchat: loading ftplugin")
4+
5+
vim.opt_local.swapfile = false
6+
vim.opt_local.wrap = true
7+
vim.opt_local.linebreak = true
8+
9+
local buf = vim.api.nvim_get_current_buf()
10+
local ns_id = vim.api.nvim_create_namespace("GpChatExt_" .. buf)
11+
12+
-- ensure normal mode
13+
vim.cmd.stopinsert()
14+
M.helpers.feedkeys("<esc>", "xn")
15+
16+
M.logger.debug("gpchat: ns_id " .. ns_id .. " for buffer " .. buf)
17+
18+
if M.config.chat_prompt_buf_type then
19+
vim.api.nvim_set_option_value("buftype", "prompt", { buf = buf })
20+
vim.fn.prompt_setprompt(buf, "")
21+
vim.fn.prompt_setcallback(buf, function()
22+
M.cmd.ChatRespond({ args = "" })
23+
end)
24+
end
25+
26+
-- setup chat specific commands
27+
local commands = {
28+
{
29+
command = "ChatRespond",
30+
modes = M.config.chat_shortcut_respond.modes,
31+
shortcut = M.config.chat_shortcut_respond.shortcut,
32+
comment = "GPT prompt Chat Respond",
33+
},
34+
{
35+
command = "ChatNew",
36+
modes = M.config.chat_shortcut_new.modes,
37+
shortcut = M.config.chat_shortcut_new.shortcut,
38+
comment = "GPT prompt Chat New",
39+
},
40+
}
41+
for _, rc in ipairs(commands) do
42+
local cmd = M.config.cmd_prefix .. rc.command .. "<cr>"
43+
for _, mode in ipairs(rc.modes) do
44+
if mode == "n" or mode == "i" then
45+
M.helpers.set_keymap({ buf }, mode, rc.shortcut, function()
46+
vim.api.nvim_command(M.config.cmd_prefix .. rc.command)
47+
-- go to normal mode
48+
vim.api.nvim_command("stopinsert")
49+
M.helpers.feedkeys("<esc>", "xn")
50+
end, rc.comment)
51+
else
52+
M.helpers.set_keymap({ buf }, mode, rc.shortcut, ":<C-u>'<,'>" .. cmd, rc.comment)
53+
end
54+
end
55+
end
56+
57+
local ds = M.config.chat_shortcut_delete
58+
M.helpers.set_keymap({ buf }, ds.modes, ds.shortcut, M.cmd.ChatDelete, "GPT prompt Chat Delete")
59+
60+
local ss = M.config.chat_shortcut_stop
61+
M.helpers.set_keymap({ buf }, ss.modes, ss.shortcut, M.cmd.Stop, "GPT prompt Chat Stop")
62+
63+
-- conceal parameters in model header so it's not distracting
64+
if M.config.chat_conceal_model_params then
65+
vim.opt_local.conceallevel = 2
66+
vim.opt_local.concealcursor = ""
67+
vim.fn.matchadd("Conceal", [[^- model: .*model.:.[^"]*\zs".*\ze]], 10, -1, { conceal = "" })
68+
vim.fn.matchadd("Conceal", [[^- model: \zs.*model.:.\ze.*]], 10, -1, { conceal = "" })
69+
vim.fn.matchadd("Conceal", [[^- role: .\{64,64\}\zs.*\ze]], 10, -1, { conceal = "" })
70+
vim.fn.matchadd("Conceal", [[^- role: .[^\\]*\zs\\.*\ze]], 10, -1, { conceal = "" })
71+
end
72+
73+
vim.api.nvim_create_autocmd({ "BufEnter", "WinEnter" }, {
74+
buffer = buf,
75+
callback = function(event)
76+
if M.helpers.deleted_invalid_autocmd(buf, event) then
77+
return
78+
end
79+
-- M.logger.debug("gpchat: entering buffer " .. buf .. " " .. vim.json.encode(event))
80+
81+
vim.cmd("doautocmd User GpRefresh")
82+
end,
83+
})
84+
85+
vim.api.nvim_create_autocmd({ "BufEnter", "TextChanged", "InsertLeave" }, {
86+
buffer = buf,
87+
callback = function(event)
88+
if M.helpers.deleted_invalid_autocmd(buf, event) then
89+
return
90+
end
91+
-- M.logger.debug("gpchat: saving buffer " .. buf .. " " .. vim.json.encode(event))
92+
vim.api.nvim_command("silent! write")
93+
end,
94+
})
95+
vim.api.nvim_create_autocmd({ "User" }, {
96+
callback = function(event)
97+
if event.event == "User" and event.match ~= "GpRefresh" then
98+
return
99+
end
100+
if M.helpers.deleted_invalid_autocmd(buf, event) then
101+
return
102+
end
103+
104+
M.logger.debug("gpchat: refreshing buffer " .. buf .. " " .. vim.json.encode(event))
105+
106+
vim.api.nvim_buf_clear_namespace(buf, ns_id, 0, -1)
107+
108+
vim.api.nvim_buf_set_extmark(buf, ns_id, 0, 0, {
109+
strict = false,
110+
right_gravity = true,
111+
virt_text_pos = "right_align",
112+
virt_text = {
113+
{ "Current Agent: [" .. M._state.chat_agent .. "]", "DiagnosticHint" },
114+
},
115+
hl_mode = "combine",
116+
})
117+
end,
118+
})

lua/gp/init.lua

Lines changed: 5 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,14 @@ M.setup = function(opts)
208208
end
209209
end
210210

211-
M.buf_handler()
212211
vim.filetype.add({
213212
extension = {
214213
md = function(path, buf)
215214
M.logger.debug("filetype markdown: " .. path .. " buf: " .. buf)
215+
if not M.not_chat(buf, path) then
216+
return "markdown.gpchat"
217+
end
218+
216219
if M.helpers.ends_with(path, ".gp.md") then
217220
return "markdown.gpmd"
218221
end
@@ -286,9 +289,7 @@ M.refresh_state = function(update)
286289

287290
M.prepare_commands()
288291

289-
local buf = vim.api.nvim_get_current_buf()
290-
local file_name = vim.api.nvim_buf_get_name(buf)
291-
M.display_chat_agent(buf, file_name)
292+
vim.cmd("doautocmd User GpRefresh")
292293
end
293294

294295
M.Target = {
@@ -439,23 +440,6 @@ M._toggle_resolve = function(kind)
439440
return M._toggle_kind.unknown
440441
end
441442

442-
---@param buf number | nil # buffer number
443-
M.prep_md = function(buf)
444-
-- disable swapping for this buffer and set filetype to markdown
445-
vim.api.nvim_command("setlocal noswapfile")
446-
-- better text wrapping
447-
vim.api.nvim_command("setlocal wrap linebreak")
448-
-- auto save on TextChanged, InsertLeave
449-
vim.api.nvim_command("autocmd TextChanged,InsertLeave <buffer=" .. buf .. "> silent! write")
450-
451-
-- register shortcuts local to this buffer
452-
buf = buf or vim.api.nvim_get_current_buf()
453-
454-
-- ensure normal mode
455-
vim.api.nvim_command("stopinsert")
456-
M.helpers.feedkeys("<esc>", "xn")
457-
end
458-
459443
---@param buf number # buffer number
460444
---@param file_name string # file name
461445
---@return string | nil # reason for not being a chat or nil if it is a chat
@@ -490,133 +474,6 @@ M.not_chat = function(buf, file_name)
490474
return nil
491475
end
492476

493-
M.display_chat_agent = function(buf, file_name)
494-
if M.not_chat(buf, file_name) then
495-
return
496-
end
497-
498-
if buf ~= vim.api.nvim_get_current_buf() then
499-
return
500-
end
501-
502-
local ns_id = vim.api.nvim_create_namespace("GpChatExt_" .. file_name)
503-
vim.api.nvim_buf_clear_namespace(buf, ns_id, 0, -1)
504-
505-
vim.api.nvim_buf_set_extmark(buf, ns_id, 0, 0, {
506-
strict = false,
507-
right_gravity = true,
508-
virt_text_pos = "right_align",
509-
virt_text = {
510-
{ "Current Agent: [" .. M._state.chat_agent .. "]", "DiagnosticHint" },
511-
},
512-
hl_mode = "combine",
513-
})
514-
end
515-
516-
M._prepared_bufs = {}
517-
M.prep_chat = function(buf, file_name)
518-
if M.not_chat(buf, file_name) then
519-
return
520-
end
521-
522-
if buf ~= vim.api.nvim_get_current_buf() then
523-
return
524-
end
525-
526-
M.refresh_state({ last_chat = file_name })
527-
if M._prepared_bufs[buf] then
528-
M.logger.debug("buffer already prepared: " .. buf)
529-
return
530-
end
531-
M._prepared_bufs[buf] = true
532-
533-
M.prep_md(buf)
534-
535-
if M.config.chat_prompt_buf_type then
536-
vim.api.nvim_set_option_value("buftype", "prompt", { buf = buf })
537-
vim.fn.prompt_setprompt(buf, "")
538-
vim.fn.prompt_setcallback(buf, function()
539-
M.cmd.ChatRespond({ args = "" })
540-
end)
541-
end
542-
543-
-- setup chat specific commands
544-
local range_commands = {
545-
{
546-
command = "ChatRespond",
547-
modes = M.config.chat_shortcut_respond.modes,
548-
shortcut = M.config.chat_shortcut_respond.shortcut,
549-
comment = "GPT prompt Chat Respond",
550-
},
551-
{
552-
command = "ChatNew",
553-
modes = M.config.chat_shortcut_new.modes,
554-
shortcut = M.config.chat_shortcut_new.shortcut,
555-
comment = "GPT prompt Chat New",
556-
},
557-
}
558-
for _, rc in ipairs(range_commands) do
559-
local cmd = M.config.cmd_prefix .. rc.command .. "<cr>"
560-
for _, mode in ipairs(rc.modes) do
561-
if mode == "n" or mode == "i" then
562-
M.helpers.set_keymap({ buf }, mode, rc.shortcut, function()
563-
vim.api.nvim_command(M.config.cmd_prefix .. rc.command)
564-
-- go to normal mode
565-
vim.api.nvim_command("stopinsert")
566-
M.helpers.feedkeys("<esc>", "xn")
567-
end, rc.comment)
568-
else
569-
M.helpers.set_keymap({ buf }, mode, rc.shortcut, ":<C-u>'<,'>" .. cmd, rc.comment)
570-
end
571-
end
572-
end
573-
574-
local ds = M.config.chat_shortcut_delete
575-
M.helpers.set_keymap({ buf }, ds.modes, ds.shortcut, M.cmd.ChatDelete, "GPT prompt Chat Delete")
576-
577-
local ss = M.config.chat_shortcut_stop
578-
M.helpers.set_keymap({ buf }, ss.modes, ss.shortcut, M.cmd.Stop, "GPT prompt Chat Stop")
579-
580-
-- conceal parameters in model header so it's not distracting
581-
if M.config.chat_conceal_model_params then
582-
vim.opt_local.conceallevel = 2
583-
vim.opt_local.concealcursor = ""
584-
vim.fn.matchadd("Conceal", [[^- model: .*model.:.[^"]*\zs".*\ze]], 10, -1, { conceal = "" })
585-
vim.fn.matchadd("Conceal", [[^- model: \zs.*model.:.\ze.*]], 10, -1, { conceal = "" })
586-
vim.fn.matchadd("Conceal", [[^- role: .\{64,64\}\zs.*\ze]], 10, -1, { conceal = "" })
587-
vim.fn.matchadd("Conceal", [[^- role: .[^\\]*\zs\\.*\ze]], 10, -1, { conceal = "" })
588-
end
589-
end
590-
591-
M.buf_handler = function()
592-
local gid = M.helpers.create_augroup("GpBufHandler", { clear = true })
593-
594-
M.helpers.autocmd({ "BufEnter" }, nil, function(event)
595-
local buf = event.buf
596-
597-
if not vim.api.nvim_buf_is_valid(buf) then
598-
return
599-
end
600-
601-
local file_name = vim.api.nvim_buf_get_name(buf)
602-
603-
M.prep_chat(buf, file_name)
604-
M.display_chat_agent(buf, file_name)
605-
end, gid)
606-
607-
M.helpers.autocmd({ "WinEnter" }, nil, function(event)
608-
local buf = event.buf
609-
610-
if not vim.api.nvim_buf_is_valid(buf) then
611-
return
612-
end
613-
614-
local file_name = vim.api.nvim_buf_get_name(buf)
615-
616-
M.display_chat_agent(buf, file_name)
617-
end, gid)
618-
end
619-
620477
M.BufTarget = {
621478
current = 0, -- current window
622479
popup = 1, -- popup window

0 commit comments

Comments
 (0)