fix: buffer handling

This commit is contained in:
2024-12-29 16:39:58 +01:00
parent 40c9d5672d
commit 162ab2d820
3 changed files with 61 additions and 26 deletions

View File

@@ -80,11 +80,6 @@ end
-----------------------------------------------------------------------------
-- CHUNKING
-----------------------------------------------------------------------------
-- If chunking is enabled and we exceed the token limit, we split the prompt
-- into multiple chunks. We then copy each chunk in turn to the clipboard.
-- The user can paste them one by one into ChatGPT. This is a naive approach,
-- but helps with extremely large requests.
-----------------------------------------------------------------------------
local function handle_chunking_if_needed(prompt, estimate_fn)
local conf = config.load()
local token_count = estimate_fn(prompt)
@@ -96,14 +91,26 @@ local function handle_chunking_if_needed(prompt, estimate_fn)
return chunks
end
-- Close an existing buffer by name (if it exists)
local function close_existing_buffer_by_name(pattern)
for _, b in ipairs(vim.api.nvim_list_bufs()) do
local name = vim.api.nvim_buf_get_name(b)
if name:match(pattern) then
vim.api.nvim_buf_delete(b, { force = true })
end
end
end
-- Show the user a preview buffer with the proposed changes (unchanged).
local function preview_changes(changes)
close_existing_buffer_by_name("ChatGPT_Changes_Preview$")
local bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(bufnr, "ChatGPT_Changes_Preview")
vim.api.nvim_buf_set_option(bufnr, "filetype", "diff")
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
"# Preview of Changes:",
"# (Close this window to apply changes or run :q to cancel)",
"# (Close this window to apply changes or use :q to cancel)",
""
})
for _, fileinfo in ipairs(changes) do
@@ -126,12 +133,14 @@ end
-- Minimal partial acceptance from previous example
local function partial_accept(changes)
close_existing_buffer_by_name("ChatGPT_Partial_Accept$")
local bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(bufnr, "ChatGPT_Partial_Accept")
vim.api.nvim_buf_set_option(bufnr, "filetype", "diff")
local lines = {
"# Remove or comment out (prepend '#') any changes you do NOT want, then :wq to finalize partial acceptance",
"# Remove or comment out (prepend '#') any changes you do NOT want, then :wq, :x, or :bd to finalize partial acceptance",
""
}
for _, fileinfo in ipairs(changes) do
@@ -202,7 +211,10 @@ local function partial_accept(changes)
vim.api.nvim_create_autocmd("BufWriteCmd", {
buffer = bufnr,
once = true,
callback = on_write
callback = function()
on_write()
vim.cmd("bd! " .. bufnr) -- auto-close buffer
end
})
vim.cmd("split")
@@ -224,6 +236,8 @@ end
-- Utility to store generated prompt in a scratch buffer
local function store_prompt_for_reference(prompt)
close_existing_buffer_by_name("ChatGPT_Generated_Prompt$")
local bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(bufnr, "ChatGPT_Generated_Prompt")
vim.api.nvim_buf_set_option(bufnr, "filetype", "markdown")
@@ -258,6 +272,9 @@ function M.run_chatgpt_command()
end
end
-- Close existing prompt buffer if open
close_existing_buffer_by_name("ChatGPT_Prompt.md$")
local bufnr = vim.api.nvim_create_buf(false, false)
vim.api.nvim_buf_set_name(bufnr, "ChatGPT_Prompt.md")
vim.api.nvim_buf_set_option(bufnr, "filetype", "markdown")
@@ -268,7 +285,7 @@ function M.run_chatgpt_command()
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
"# Enter your prompt below.",
"",
"Save & close with :wq to finalize your prompt."
"Save & close with :wq, :x, or :bd to finalize your prompt."
})
vim.api.nvim_create_autocmd("BufWriteCmd", {
@@ -325,19 +342,20 @@ function M.run_chatgpt_command()
local chunks = handle_chunking_if_needed(prompt, estimate_fn)
if #chunks == 1 then
-- Single chunk, just copy as normal
copy_to_clipboard(chunks[1])
vim.api.nvim_out_write("Prompt copied to clipboard! Paste into ChatGPT.\n")
else
-- Multiple chunks. We'll store them in separate scratch buffers and also copy the first chunk
-- Multiple chunks. We'll create separate scratch buffers
for i, chunk in ipairs(chunks) do
close_existing_buffer_by_name("ChatGPT_Generated_Chunk_" .. i .. "$")
local cbuf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(cbuf, "ChatGPT_Generated_Chunk_" .. i)
vim.api.nvim_buf_set_option(cbuf, "filetype", "markdown")
local lines = {
"# Chunk " .. i .. " of " .. #chunks .. ":",
"# Copy/paste this chunk into ChatGPT, then come back and copy next chunk as needed.",
"# Copy/paste this chunk into ChatGPT, then come back and copy the next chunk as needed.",
""
}
vim.list_extend(lines, vim.split(chunk, "\n"))
@@ -393,7 +411,7 @@ function M.run_chatgpt_paste_command()
if is_final then
if conf.preview_changes then
preview_changes(data.files)
print("Close the preview window to apply changes, or leave it open and use :q to cancel.")
print("Close the preview window to apply changes, or use :q to cancel.")
local closed = vim.wait(60000, function()
local bufs = vim.api.nvim_list_bufs()
for _, b in ipairs(bufs) do
@@ -513,4 +531,4 @@ function M.run_chatgpt_paste_command()
end
end
return M
return M