From f1cc37129468eea2212e045d82d2d9a60fb7e4d1 Mon Sep 17 00:00:00 2001 From: Dominik Polakovics Date: Sun, 5 Jan 2025 17:11:13 +0100 Subject: [PATCH] feat: change commands to accept args --- lua/chatgpt_nvim/init.lua | 146 +++++++++++++++++++++-------------- lua/chatgpt_nvim/prompts.lua | 14 ++-- 2 files changed, 97 insertions(+), 63 deletions(-) diff --git a/lua/chatgpt_nvim/init.lua b/lua/chatgpt_nvim/init.lua index 384f7c8..4f363c7 100644 --- a/lua/chatgpt_nvim/init.lua +++ b/lua/chatgpt_nvim/init.lua @@ -12,7 +12,6 @@ local function copy_to_clipboard(text) vim.fn.setreg('+', text) end --- Expecting 'conf' instead of loading config in parse_response: local function parse_response(raw, conf) if not ok_yaml then vim.api.nvim_err_writeln("lyaml not available. Install with `luarocks install lyaml`.") @@ -54,7 +53,6 @@ local function is_directory(path) return stat and stat.type == "directory" end --- Expect 'conf' instead of loading config in handle_step_by_step_if_needed: local function handle_step_by_step_if_needed(prompt, conf) local length = #prompt if not conf.enable_step_by_step or length <= (conf.prompt_char_limit or 8000) then @@ -221,6 +219,7 @@ local function store_prompt_for_reference(prompt, conf) vim.cmd("buffer " .. bufnr) end +-- Updated to allow flags/args for 'ls' and 'grep' local function execute_debug_command(cmd, conf) if type(cmd) ~= "table" or not cmd.command then return "Invalid command object." @@ -228,81 +227,109 @@ local function execute_debug_command(cmd, conf) local command = cmd.command if command == "ls" then + -- Accept optional flags/args local dir = cmd.dir or "." - local handle = io.popen("ls " .. dir) + local args = cmd.args or {} + local cmd_str = "ls" + if #args > 0 then + cmd_str = cmd_str .. " " .. table.concat(args, " ") + end + cmd_str = cmd_str .. " " .. dir + + local handle = io.popen(cmd_str) if not handle then return "Failed to run ls command." end local result = handle:read("*a") or "" handle:close() return "Listing files in: " .. dir .. "\n" .. result + elseif command == "grep" then - local pattern = cmd.pattern - local target = cmd.target - if not pattern or not target then - return "Usage for grep: {command='grep', pattern='', target=''}" - end - local stat = vim.loop.fs_stat(target) - if not stat then - return "Cannot grep: target path does not exist" - end - if stat.type == "directory" then - local handle = io.popen("ls -p " .. target .. " | grep -v /") - if not handle then - return "Failed to read directory contents for grep." + -- Accept optional flags/args + -- If the user wants to do something like: + -- args: ["-r", "somePattern", "someDir"] + -- we just pass them all to grep. + local args = cmd.args or {} + if #args == 0 then + -- fallback to old usage + local pattern = cmd.pattern + local target = cmd.target + if not pattern or not target then + return "Usage for grep: {command='grep', args=['-r','pattern','target']} or {pattern='', target=''}" end - local all_files = {} - for file in handle:read("*a"):gmatch("[^\n]+") do - table.insert(all_files, target .. "/" .. file) + local stat = vim.loop.fs_stat(target) + if not stat then + return "Cannot grep: target path does not exist" end - handle:close() - local results = {} - local function grep_in_file(search_string, filepath) - local content = read_file(filepath) - if not content then - return "Could not read file: " .. filepath + -- old logic remains for backward compatibility + if stat.type == "directory" then + local handle = io.popen("ls -p " .. target .. " | grep -v /") + if not handle then + return "Failed to read directory contents for grep." end - local lines = {} - local line_num = 0 - for line in content:gmatch("([^\n]*)\n?") do - line_num = line_num + 1 - if line:find(search_string, 1, true) then - table.insert(lines, filepath .. ":" .. line_num .. ":" .. line) + local all_files = {} + for file in handle:read("*a"):gmatch("[^\n]+") do + table.insert(all_files, target .. "/" .. file) + end + handle:close() + local results = {} + local function grep_in_file(search_string, filepath) + local content = read_file(filepath) + if not content then + return "Could not read file: " .. filepath + end + local lines = {} + local line_num = 0 + for line in content:gmatch("([^\n]*)\n?") do + line_num = line_num + 1 + if line:find(search_string, 1, true) then + table.insert(lines, filepath .. ":" .. line_num .. ":" .. line) + end + end + return (#lines == 0) and ("No matches in " .. filepath) or table.concat(lines, "\n") + end + for _, f in ipairs(all_files) do + local fstat = vim.loop.fs_stat(f) + if fstat and fstat.type == "file" then + table.insert(results, grep_in_file(pattern, f)) end end - return (#lines == 0) and ("No matches in " .. filepath) or table.concat(lines, "\n") - end - for _, f in ipairs(all_files) do - local fstat = vim.loop.fs_stat(f) - if fstat and fstat.type == "file" then - table.insert(results, grep_in_file(pattern, f)) + return table.concat(results, "\n") + else + local function grep_in_file(search_string, filepath) + local content = read_file(filepath) + if not content then + return "Could not read file: " .. filepath + end + local lines = {} + local line_num = 0 + for line in content:gmatch("([^\n]*)\n?") do + line_num = line_num + 1 + if line:find(search_string, 1, true) then + table.insert(lines, filepath .. ":" .. line_num .. ":" .. line) + end + end + return (#lines == 0) and ("No matches in " .. filepath) or table.concat(lines, "\n") end + return grep_in_file(pattern, target) end - return table.concat(results, "\n") else - local function grep_in_file(search_string, filepath) - local content = read_file(filepath) - if not content then - return "Could not read file: " .. filepath - end - local lines = {} - local line_num = 0 - for line in content:gmatch("([^\n]*)\n?") do - line_num = line_num + 1 - if line:find(search_string, 1, true) then - table.insert(lines, filepath .. ":" .. line_num .. ":" .. line) - end - end - return (#lines == 0) and ("No matches in " .. filepath) or table.concat(lines, "\n") + -- new approach with flags/args + local cmd_str = "grep " .. table.concat(args, " ") + local handle = io.popen(cmd_str) + if not handle then + return "Failed to run grep command." end - return grep_in_file(pattern, target) + local result = handle:read("*a") or "" + handle:close() + return result end else return "Unknown command: " .. command end end -function M.run_chatgpt_command() +local function run_chatgpt_command() local conf = config.load() ui.setup_ui(conf) ui.debug_log("Running :ChatGPT command.") @@ -398,7 +425,7 @@ function M.run_chatgpt_command() vim.cmd("buffer " .. bufnr) end -function M.run_chatgpt_paste_command() +local function run_chatgpt_paste_command() local conf = config.load() ui.setup_ui(conf) ui.debug_log("Running :ChatGPTPaste command.") @@ -545,7 +572,7 @@ function M.run_chatgpt_paste_command() end end -function M.run_chatgpt_current_buffer_command() +local function run_chatgpt_current_buffer_command() local conf = config.load() ui.setup_ui(conf) ui.debug_log("Running :ChatGPTCurrentBuffer command.") @@ -653,4 +680,9 @@ function M.run_chatgpt_current_buffer_command() end end -return M \ No newline at end of file +M.run_chatgpt_command = run_chatgpt_command +M.run_chatgpt_paste_command = run_chatgpt_paste_command +M.run_chatgpt_current_buffer_command = run_chatgpt_current_buffer_command +M.execute_debug_command = execute_debug_command + +return M diff --git a/lua/chatgpt_nvim/prompts.lua b/lua/chatgpt_nvim/prompts.lua index 282557a..4a8ba21 100644 --- a/lua/chatgpt_nvim/prompts.lua +++ b/lua/chatgpt_nvim/prompts.lua @@ -74,16 +74,18 @@ local M = { ```yaml commands: - - command: "list" - dir: "some/directory" + - command: "ls" + args: ["-l", "path/to/directory"] - command: "grep" - pattern: "searchString" - target: "path/to/file/or/directory" + args: ["-r", "searchString", "path/to/file/or/directory"] ``` - The "ls" command uses the system's 'ls' command to list directory contents. - When these commands are present and enable_debug_commands is true, I'll execute them and return the results in the clipboard. + The "ls" command uses the system's 'ls' command to list directory contents. You can pass flags or additional arguments in `args`. + The "grep" command searches for a given pattern in files or directories, again receiving flags or additional arguments in `args`. + If you omit `args` for grep, you can still use the older format with `pattern` and `target` for backward compatibility. + + When these commands are present and `enable_debug_commands` is true, I'll execute them and return the results in the clipboard. ]] }