diff --git a/lua/gp/config.lua b/lua/gp/config.lua index c80c3c5..5741298 100644 --- a/lua/gp/config.lua +++ b/lua/gp/config.lua @@ -355,6 +355,8 @@ local config = { -- auto select command response (easier chaining of commands) -- if false it also frees up the buffer cursor for further editing elsewhere command_auto_select_response = true, + -- if enabled, will use a floating window + scratch buffer for reading user command + command_floating_window = false, -- templates template_selection = "I have the following from {{filename}}:" diff --git a/lua/gp/helper.lua b/lua/gp/helper.lua index 1864bde..3750118 100644 --- a/lua/gp/helper.lua +++ b/lua/gp/helper.lua @@ -293,4 +293,71 @@ _H.create_user_command = function(cmd_name, cmd_func, completion, desc) }) end +_H.floating_input = function(opts, cb) + if not opts.accept_shortcut or not opts.accept_modes then + error('accept_shortcut and accept_modes must be provided for floating_input()') + end + + -- Create a scratch buffer + local buf = vim.api.nvim_create_buf(false, true) + + -- Set buffer options + vim.api.nvim_buf_set_option(buf, 'bufhidden', 'wipe') + vim.api.nvim_buf_set_option(buf, 'buftype', 'nofile') + + -- Calculate window size and position + local width = opts.width or math.floor(vim.api.nvim_win_get_width(0) / 2) + local height = opts.height or math.floor(vim.api.nvim_win_get_height(0) / 2) + local win_opts = { + relative = 'editor', + width = width, + height = height, + col = math.floor((vim.o.columns - width) / 2), + row = math.floor((vim.o.lines - height) / 2), + style = 'minimal', + border = 'rounded' + } + + -- Create window + local win = vim.api.nvim_open_win(buf, true, win_opts) + + -- Add title if prompt is provided + if opts.prompt then + vim.api.nvim_win_set_option(win, 'winhl', 'Normal:Normal') + vim.api.nvim_buf_set_lines(buf, 0, -1, false, {opts.prompt, ""}) + vim.api.nvim_win_set_cursor(win, {2, 0}) + end + + -- Set default content if provided + if opts.default and opts.default ~= "" then + vim.api.nvim_buf_set_lines(buf, -1, -1, false, {opts.default}) + end + + -- Set up the key mapping to accept the input + vim.keymap.set(opts.accept_modes, opts.accept_shortcut, function() + -- Get buffer content + local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false) + + -- Remove prompt and empty line if they exist + if opts.prompt and lines[1] == opts.prompt then + table.remove(lines, 1) -- Remove prompt line + if lines[1] == "" then + table.remove(lines, 1) -- Remove empty line after prompt + end + end + + local content = table.concat(lines, '\n') + + -- Close the window + vim.api.nvim_win_close(win, true) + + -- Invoke the callback with the content + cb(content) + end, { buffer = buf, nowait = true }) + + vim.schedule(function() + vim.api.nvim_command("startinsert") + end) +end + return _H diff --git a/lua/gp/init.lua b/lua/gp/init.lua index 128914c..019b93b 100644 --- a/lua/gp/init.lua +++ b/lua/gp/init.lua @@ -1485,7 +1485,6 @@ end -------------------------------------------------------------------------------- -- Prompt logic -------------------------------------------------------------------------------- - M.cmd.Agent = function(params) local agent_name = string.gsub(params.args, "^%s*(.-)%s*$", "%1") if agent_name == "" then @@ -1952,13 +1951,24 @@ M.Prompt = function(params, target, agent, template, prompt, whisper, callback) return end - -- if prompt is provided, ask the user to enter the command - vim.ui.input({ prompt = prompt, default = whisper }, function(input) + local function input_callback(input) if not input or input == "" then return end cb(input) - end) + end + + -- if prompt is provided, ask the user to enter the command + if M.config.command_floating_window then + M.helpers.floating_input({ + prompt = prompt, + default = whisper, + accept_shortcut = M.config.chat_shortcut_respond.shortcut, + accept_modes = M.config.chat_shortcut_respond.modes + }, input_callback) + else + vim.ui.input({ prompt = prompt, default = whisper }, input_callback) + end end) end