fix(nvim): eliminate \r corruption in buffer mutations

- Pre-process and strip carriage returns natively in Rust before RPC serialization.

- Pass replacement strings to Neovim as native MsgPack arrays to bypass Lua vim.split overhead.

- Directly feed table arrays into vim.api.nvim_buf_set_lines for exact buffer matches.
This commit is contained in:
Riz Ashraf committed 2026-10-08 23:58:49 +01:00
1 parent cb0c55775a
commit d6acd885dd
1 file changed
+20 -8
+20 -8
View File
@@ -1326,7 +1326,14 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
) )
} }
"edit" => { "edit" => {
let args_rmp = json_to_rmpv(args); let mut modified_args = args.clone();
if let Some(content) = modified_args.get_mut("replacement_content") {
if let Some(s) = content.as_str() {
let lines: Vec<String> = 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 = " let code = "
local args = ... local args = ...
local file = args.file local file = args.file
@@ -1341,8 +1348,8 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
if not end_line then if not end_line then
error(\"Missing 'end_line'\") error(\"Missing 'end_line'\")
end end
local content = args.replacement_content local content_lines = args.replacement_content
if not content or content == vim.NIL then if not content_lines or content_lines == vim.NIL then
error(\"Missing 'replacement_content'\") error(\"Missing 'replacement_content'\")
end end
@@ -1351,8 +1358,7 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
vim.fn.bufload(bufnr) vim.fn.bufload(bufnr)
end end
local lines = vim.split(content, '\\n', { plain = true }) vim.api.nvim_buf_set_lines(bufnr, start_line - 1, end_line, false, content_lines)
vim.api.nvim_buf_set_lines(bufnr, start_line - 1, end_line, false, lines)
local win = vim.fn.bufwinid(bufnr) local win = vim.fn.bufwinid(bufnr)
if win ~= -1 then if win ~= -1 then
@@ -1398,7 +1404,14 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
) )
} }
"create_scratch" | "open_buffer" => { "create_scratch" | "open_buffer" => {
let args_rmp = json_to_rmpv(args); let mut modified_args = args.clone();
if let Some(content) = modified_args.get_mut("content") {
if let Some(s) = content.as_str() {
let lines: Vec<String> = 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 = " let code = "
local args = ... local args = ...
local name = (args.name and args.name ~= '') and args.name or '[Antigravity Scratch]' local name = (args.name and args.name ~= '') and args.name or '[Antigravity Scratch]'
@@ -1408,8 +1421,7 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
vim.bo[buf].buftype = 'nofile' vim.bo[buf].buftype = 'nofile'
vim.bo[buf].bufhidden = 'hide' vim.bo[buf].bufhidden = 'hide'
if args.content then if args.content then
local lines = vim.split(args.content, '\\n') vim.api.nvim_buf_set_lines(buf, 0, -1, false, args.content)
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
end end
if args.filetype and args.filetype ~= '' then if args.filetype and args.filetype ~= '' then
vim.bo[buf].filetype = args.filetype vim.bo[buf].filetype = args.filetype