Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a67249ddb | ||
|
|
80b1969b15 | ||
|
|
d60d6ca70b |
No files matched your search
+55
-10
@@ -753,7 +753,7 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
"tools": [
|
"tools": [
|
||||||
{
|
{
|
||||||
"name": "nvim_goto_line",
|
"name": "nvim_goto_line",
|
||||||
"description": "Open a file and jump to a specific line",
|
"description": "Open a file and jump to a specific line. WARNING: Jumps the cursor in the active window. Do NOT use if you might disrupt the user's current workflow. Prefer nvim_split_window if investigating.",
|
||||||
"inputSchema": {
|
"inputSchema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -773,7 +773,7 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nvim_get_cursor",
|
"name": "nvim_get_cursor",
|
||||||
"description": "Get the current cursor position (line and column) in the active Neovim buffer",
|
"description": "Get the current cursor position. WARNING: Transient state. Do NOT base code edits strictly on cursor position. Use absolute line numbers.",
|
||||||
"inputSchema": {
|
"inputSchema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {}
|
"properties": {}
|
||||||
@@ -781,7 +781,7 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nvim_get_visual_selection",
|
"name": "nvim_get_visual_selection",
|
||||||
"description": "Get the text that is currently highlighted or was last highlighted in Visual mode",
|
"description": "Get visually selected text. WARNING: Transient state. The user might have moved the cursor. Verify contents before editing.",
|
||||||
"inputSchema": {
|
"inputSchema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {}
|
"properties": {}
|
||||||
@@ -793,7 +793,7 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
"inputSchema": {
|
"inputSchema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"line": { "type": "integer" },
|
"line": { "type": "integer", "description": "Line number (1-indexed)" },
|
||||||
"message": { "type": "string" }
|
"message": { "type": "string" }
|
||||||
},
|
},
|
||||||
"required": ["line", "message"]
|
"required": ["line", "message"]
|
||||||
@@ -805,7 +805,7 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
"inputSchema": {
|
"inputSchema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"line": { "type": "integer" },
|
"line": { "type": "integer", "description": "Line number (1-indexed)" },
|
||||||
"text": { "type": "string" },
|
"text": { "type": "string" },
|
||||||
"highlight_group": { "type": "string", "description": "Optional. E.g., 'DiagnosticVirtualTextInfo', 'Comment'" }
|
"highlight_group": { "type": "string", "description": "Optional. E.g., 'DiagnosticVirtualTextInfo', 'Comment'" }
|
||||||
},
|
},
|
||||||
@@ -973,8 +973,8 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"buf_id": { "type": "integer" },
|
"buf_id": { "type": "integer" },
|
||||||
"start_line": { "type": "integer" },
|
"start_line": { "type": "integer", "description": "1-indexed start line" },
|
||||||
"end_line": { "type": "integer" },
|
"end_line": { "type": "integer", "description": "1-indexed end line" },
|
||||||
"group": { "type": "string" },
|
"group": { "type": "string" },
|
||||||
"duration_ms": { "type": "integer", "description": "Duration to show highlight in milliseconds. Set to 0 for permanent (until cleared manually)." },
|
"duration_ms": { "type": "integer", "description": "Duration to show highlight in milliseconds. Set to 0 for permanent (until cleared manually)." },
|
||||||
"clear_only": { "type": "boolean", "description": "If true, will only clear existing highlights and ignore start/end lines." }
|
"clear_only": { "type": "boolean", "description": "If true, will only clear existing highlights and ignore start/end lines." }
|
||||||
@@ -1024,6 +1024,14 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
},
|
},
|
||||||
"required": ["file", "pattern"]
|
"required": ["file", "pattern"]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "nvim_get_server_info",
|
||||||
|
"description": "Get diagnostic info about this MCP server (OS, version, executable path, backend)",
|
||||||
|
"inputSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})),
|
})),
|
||||||
@@ -1342,12 +1350,23 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
let code = "
|
let code = "
|
||||||
local first = vim.fn.line('w0')
|
local first = vim.fn.line('w0')
|
||||||
local last = vim.fn.line('w$')
|
local last = vim.fn.line('w$')
|
||||||
|
local total = vim.api.nvim_buf_line_count(0)
|
||||||
local lines = vim.api.nvim_buf_get_lines(0, first - 1, last, false)
|
local lines = vim.api.nvim_buf_get_lines(0, first - 1, last, false)
|
||||||
local res = {}
|
local res = {}
|
||||||
for i, line in ipairs(lines) do
|
for i, line in ipairs(lines) do
|
||||||
table.insert(res, tostring(first + i - 1) .. ': ' .. line)
|
table.insert(res, tostring(first + i - 1) .. ': ' .. line)
|
||||||
end
|
end
|
||||||
return table.concat(res, '\\n')
|
local content = table.concat(res, '\\n')
|
||||||
|
|
||||||
|
local pct = math.floor(((last - first + 1) / total) * 100)
|
||||||
|
local result = {
|
||||||
|
viewport_start = first,
|
||||||
|
viewport_end = last,
|
||||||
|
total_buffer_lines = total,
|
||||||
|
warning = string.format('You are only seeing %d%% of this file. Do not assume variables are undefined just because they are not in the viewport.', pct),
|
||||||
|
content = content
|
||||||
|
}
|
||||||
|
return result
|
||||||
";
|
";
|
||||||
match execute_nvim_lua(code).await {
|
match execute_nvim_lua(code).await {
|
||||||
Ok(res) => send_text_result!(id.clone(), res),
|
Ok(res) => send_text_result!(id.clone(), res),
|
||||||
@@ -1402,14 +1421,28 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
end
|
end
|
||||||
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
|
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
|
||||||
local matches = {{}}
|
local matches = {{}}
|
||||||
|
|
||||||
|
local pcall_ok, _ = pcall(function()
|
||||||
for i, line in ipairs(lines) do
|
for i, line in ipairs(lines) do
|
||||||
if string.match(line, pattern) then
|
if vim.fn.match(line, '\\\\v' .. pattern) >= 0 then
|
||||||
table.insert(matches, tostring(i) .. ': ' .. line)
|
table.insert(matches, tostring(i) .. ': ' .. line)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if #matches == 0 then
|
end)
|
||||||
|
|
||||||
|
if not pcall_ok or #matches == 0 then
|
||||||
|
matches = {{}}
|
||||||
|
for i, line in ipairs(lines) do
|
||||||
|
if string.find(line, pattern, 1, true) then
|
||||||
|
table.insert(matches, tostring(i) .. ': ' .. line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #matches > 0 then
|
||||||
|
table.insert(matches, 1, 'Regex failed or no results, but found these literal matches:')
|
||||||
|
else
|
||||||
return 'No matches found.'
|
return 'No matches found.'
|
||||||
end
|
end
|
||||||
|
end
|
||||||
return table.concat(matches, '\\n')
|
return table.concat(matches, '\\n')
|
||||||
");
|
");
|
||||||
match execute_nvim_lua(&code).await {
|
match execute_nvim_lua(&code).await {
|
||||||
@@ -1452,6 +1485,18 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
send_error(id, -32602, "Missing 'code'").await;
|
send_error(id, -32602, "Missing 'code'").await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"nvim_get_server_info" => {
|
||||||
|
let os = if cfg!(windows) { "Windows" } else { "Linux" };
|
||||||
|
let exe_path = std::env::current_exe()
|
||||||
|
.map(|p| p.to_string_lossy().to_string())
|
||||||
|
.unwrap_or_else(|_| "unknown".to_string());
|
||||||
|
let socket = get_socket_path().await.unwrap_or_else(|e| format!("Error: {}", e));
|
||||||
|
let info = format!(
|
||||||
|
"Server: {}\nVersion: {}\nOS: {}\nExecutable: {}\nBackend Socket: {}",
|
||||||
|
app_name, app_version, os, exe_path, socket
|
||||||
|
);
|
||||||
|
send_text_result!(id, info);
|
||||||
|
}
|
||||||
_ => send_error(id, -32601, "Method not found").await,
|
_ => send_error(id, -32601, "Method not found").await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,18 @@ pub async fn nvim_telemetry_handler(
|
|||||||
// 1. Update active_nvim.txt if FocusGained, BufEnter, or VimEnter
|
// 1. Update active_nvim.txt if FocusGained, BufEnter, or VimEnter
|
||||||
if payload.event == "FocusGained" || payload.event == "BufEnter" || payload.event == "VimEnter"
|
if payload.event == "FocusGained" || payload.event == "BufEnter" || payload.event == "VimEnter"
|
||||||
{
|
{
|
||||||
|
let session = &payload.session_id;
|
||||||
|
let is_unix_socket = session.starts_with('/') || session.starts_with('~');
|
||||||
|
|
||||||
|
if is_unix_socket {
|
||||||
|
let wsl_path = "\\\\wsl.localhost\\Ubuntu\\home\\riz\\.gemini\\active_nvim.txt";
|
||||||
|
let _ = tokio::fs::write(wsl_path, session).await;
|
||||||
|
} else {
|
||||||
let profile =
|
let profile =
|
||||||
std::env::var("USERPROFILE").unwrap_or_else(|_| "C:\\Users\\reazul.ashraf".into());
|
std::env::var("USERPROFILE").unwrap_or_else(|_| "C:\\Users\\reazul.ashraf".into());
|
||||||
let win_path = format!("{}\\.gemini\\active_nvim.txt", profile);
|
let win_path = format!("{}\\.gemini\\active_nvim.txt", profile);
|
||||||
let _ = tokio::fs::write(&win_path, &payload.session_id).await;
|
let _ = tokio::fs::write(&win_path, session).await;
|
||||||
|
}
|
||||||
let wsl_path = "\\\\wsl.localhost\\Ubuntu\\home\\riz\\.gemini\\active_nvim.txt";
|
|
||||||
let _ = tokio::fs::write(wsl_path, &payload.session_id).await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Broadcast to UI WebSockets
|
// 2. Broadcast to UI WebSockets
|
||||||
|
|||||||
Reference in new issue
Block a user