summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchristine betts <[email protected]>2025-07-24 19:54:41 +0000
committerGitHub <[email protected]>2025-07-24 19:54:41 +0000
commit4e376c0447dfb691bc4a7182d9778f81792269af (patch)
tree1c43edf6d157960f5269dea12c72f77c9df9ae56
parentf9930c2d36e73f24d6199b899c60862a4b40f9ac (diff)
[ide-mode] Send the cursor and selected text from the IDE server (#4621)
-rw-r--r--packages/vscode-ide-companion/src/extension.ts1
-rw-r--r--packages/vscode-ide-companion/src/ide-server.ts20
-rw-r--r--packages/vscode-ide-companion/src/recent-files-manager.test.ts1
-rw-r--r--packages/vscode-ide-companion/src/recent-files-manager.ts8
4 files changed, 27 insertions, 3 deletions
diff --git a/packages/vscode-ide-companion/src/extension.ts b/packages/vscode-ide-companion/src/extension.ts
index 912b9b8f..74bcaf89 100644
--- a/packages/vscode-ide-companion/src/extension.ts
+++ b/packages/vscode-ide-companion/src/extension.ts
@@ -15,7 +15,6 @@ let log: (message: string) => void = () => {};
export async function activate(context: vscode.ExtensionContext) {
logger = vscode.window.createOutputChannel('Gemini CLI IDE Companion');
log = createLogger(context, logger);
-
log('Extension activated');
ideServer = new IDEServer(log);
try {
diff --git a/packages/vscode-ide-companion/src/ide-server.ts b/packages/vscode-ide-companion/src/ide-server.ts
index 75828485..aad86a08 100644
--- a/packages/vscode-ide-companion/src/ide-server.ts
+++ b/packages/vscode-ide-companion/src/ide-server.ts
@@ -18,6 +18,7 @@ import { RecentFilesManager } from './recent-files-manager.js';
const MCP_SESSION_ID_HEADER = 'mcp-session-id';
const IDE_SERVER_PORT_ENV_VAR = 'GEMINI_CLI_IDE_SERVER_PORT';
+const MAX_SELECTED_TEXT_LENGTH = 16384; // 16 KiB limit
function sendOpenFilesChangedNotification(
transport: StreamableHTTPServerTransport,
@@ -29,6 +30,19 @@ function sendOpenFilesChangedNotification(
editor && editor.document.uri.scheme === 'file'
? editor.document.uri.fsPath
: '';
+ const selection = editor?.selection;
+ const cursor = selection
+ ? {
+ // This value is a zero-based index, but the vscode IDE is one-based.
+ line: selection.active.line + 1,
+ character: selection.active.character,
+ }
+ : undefined;
+ let selectedText = editor?.document.getText(selection) ?? undefined;
+ if (selectedText && selectedText.length > MAX_SELECTED_TEXT_LENGTH) {
+ selectedText =
+ selectedText.substring(0, MAX_SELECTED_TEXT_LENGTH) + '... [TRUNCATED]';
+ }
const notification: JSONRPCNotification = {
jsonrpc: '2.0',
method: 'ide/openFilesChanged',
@@ -37,6 +51,8 @@ function sendOpenFilesChangedNotification(
recentOpenFiles: recentFilesManager.recentFiles.filter(
(file) => file.filePath !== filePath,
),
+ cursor,
+ selectedText,
},
};
log(
@@ -69,7 +85,7 @@ export class IDEServer {
const mcpServer = createMcpServer();
const recentFilesManager = new RecentFilesManager(context);
- const disposable = recentFilesManager.onDidChange(() => {
+ const onDidChangeSubscription = recentFilesManager.onDidChange(() => {
for (const transport of Object.values(transports)) {
sendOpenFilesChangedNotification(
transport,
@@ -78,7 +94,7 @@ export class IDEServer {
);
}
});
- context.subscriptions.push(disposable);
+ context.subscriptions.push(onDidChangeSubscription);
app.post('/mcp', async (req: Request, res: Response) => {
const sessionId = req.headers[MCP_SESSION_ID_HEADER] as
diff --git a/packages/vscode-ide-companion/src/recent-files-manager.test.ts b/packages/vscode-ide-companion/src/recent-files-manager.test.ts
index 97f19f30..9d56a10d 100644
--- a/packages/vscode-ide-companion/src/recent-files-manager.test.ts
+++ b/packages/vscode-ide-companion/src/recent-files-manager.test.ts
@@ -28,6 +28,7 @@ vi.mock('vscode', () => ({
}),
window: {
onDidChangeActiveTextEditor: vi.fn(),
+ onDidChangeTextEditorSelection: vi.fn(),
},
workspace: {
onDidDeleteFiles: vi.fn(),
diff --git a/packages/vscode-ide-companion/src/recent-files-manager.ts b/packages/vscode-ide-companion/src/recent-files-manager.ts
index cbe7e9a9..317cc903 100644
--- a/packages/vscode-ide-companion/src/recent-files-manager.ts
+++ b/packages/vscode-ide-companion/src/recent-files-manager.ts
@@ -47,11 +47,19 @@ export class RecentFilesManager {
this.add(newUri);
}
});
+
+ const selectionWatcher = vscode.window.onDidChangeTextEditorSelection(
+ () => {
+ this.fireWithDebounce();
+ },
+ );
+
context.subscriptions.push(
editorWatcher,
deleteWatcher,
closeWatcher,
renameWatcher,
+ selectionWatcher,
);
}