diff --git a/nvim-core/src/lib.rs b/nvim-core/src/lib.rs index f9f458c..3afc596 100644 --- a/nvim-core/src/lib.rs +++ b/nvim-core/src/lib.rs @@ -1260,7 +1260,7 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) { handle_lua_result!(id, execute_nvim_lua(code)); } - "redo" => { + "undo" | "redo" => { let is_undo = action == "undo"; let steps = args.get("steps").and_then(|v| v.as_i64()).unwrap_or(1); let cmd = if is_undo { @@ -1283,6 +1283,37 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) { handle_lua_result!(id, execute_nvim_lua(&code)); } + "create_scratch" => { + let mut modified_args = args.clone(); + if let Some(content) = modified_args.get_mut("content") + && let Some(s) = content.as_str() + { + let lines: Vec = s + .split('\n') + .map(|l| l.trim_end_matches('\r').to_string()) + .collect(); + *content = serde_json::json!(lines); + } + let args_rmp = json_to_rmpv(&modified_args); + let code = " + local args = ... + local name = args.name or 'Scratch' + local content = args.content or {} + if type(content) == 'string' then + content = {content} + end + local bufnr = vim.api.nvim_create_buf(true, true) + pcall(vim.api.nvim_buf_set_name, bufnr, name) + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, content) + vim.api.nvim_win_set_buf(0, bufnr) + return 'Created and focused scratch buffer: ' .. name + "; + handle_lua_result!( + id, + execute_nvim_lua_with_args(code, vec![args_rmp]) + ) + } + _ => { send_error( id, @@ -1310,6 +1341,37 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) { "; handle_lua_result!(id, execute_nvim_lua(lua_code)) } + "list_windows" => { + let lua_code = r" + local wins = vim.api.nvim_list_wins() + local result = {} + for _, win in ipairs(wins) do + if vim.api.nvim_win_is_valid(win) then + local buf = vim.api.nvim_win_get_buf(win) + local name = vim.api.nvim_buf_get_name(buf) + table.insert(result, { id = win, buf_id = buf, buf_name = name }) + end + end + return vim.fn.json_encode(result) + "; + handle_lua_result!(id, execute_nvim_lua(lua_code)) + } + "focus" => { + if let Some(win_id) = args.get("win_id").and_then(|v| v.as_i64()) { + let code = format!(" + local win_id = {} + if vim.api.nvim_win_is_valid(win_id) then + vim.api.nvim_set_current_win(win_id) + return 'Focused window ' .. tostring(win_id) + else + error('Invalid window ID') + end + ", win_id); + handle_lua_result!(id, execute_nvim_lua(&code)); + } else { + send_error(id, -32602, "Missing 'win_id'").await; + } + } "split" => { let args_rmp = json_to_rmpv(args); @@ -1537,6 +1599,21 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) { return table.concat(results, "\n\n") "# } + "diagnostics" => { + r#" + local args = ... + local bufnr = vim.fn.bufnr(args.file) + if bufnr == -1 then return "Buffer not found" end + local diags = vim.diagnostic.get(bufnr) + if #diags == 0 then return "No diagnostics found" end + local results = {} + for _, d in ipairs(diags) do + local severity = vim.diagnostic.severity[d.severity] or "UNKNOWN" + table.insert(results, string.format("[%s] Line %d: %s", severity, d.lnum + 1, d.message)) + end + return table.concat(results, "\n") + "# + } _ => "", }; @@ -1584,9 +1661,9 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) { send_error(id, -32602, "Missing 'line' or 'text'").await; } } - "clear" => { + "highlight" | "clear" => { let mut modified_args = args.clone(); - if action == "clear_highlight" + if action == "clear" && let Some(obj) = modified_args.as_object_mut() { obj.insert("clear_only".to_string(), json!(true));