[ide-mode] Send the cursor and selected text from the IDE server (#4621)
This commit is contained in:
parent
f9930c2d36
commit
4e376c0447
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -28,6 +28,7 @@ vi.mock('vscode', () => ({
|
|||
}),
|
||||
window: {
|
||||
onDidChangeActiveTextEditor: vi.fn(),
|
||||
onDidChangeTextEditorSelection: vi.fn(),
|
||||
},
|
||||
workspace: {
|
||||
onDidDeleteFiles: vi.fn(),
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue