fix(vscode): preserve active editor pane

This commit is contained in:
Josh Lambert
2026-07-18 10:35:16 -04:00
parent 938919ab72
commit 85d65a3137
4 changed files with 45 additions and 38 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---
Open Kilo chats, settings, and files as tabs in the selected editor pane without creating, locking, or resizing editor panes.
@@ -64,7 +64,7 @@ export class SettingsEditorProvider implements vscode.Disposable {
const provider = this.providers.get(view)
provider?.postMessage({ type: "navigate", view, tab })
}
existing.reveal(vscode.ViewColumn.One)
existing.reveal(vscode.ViewColumn.Active)
this.providers.get(view)?.postMessage({ type: "navigate", view, ...(tab ? { tab } : {}) })
return
}
@@ -72,7 +72,7 @@ export class SettingsEditorProvider implements vscode.Disposable {
const panel = vscode.window.createWebviewPanel(
`kilo-code.new.${view}Panel`,
PANEL_TITLES[view],
vscode.ViewColumn.One,
vscode.ViewColumn.Active,
{
enableScripts: true,
retainContextWhenHidden: true,
+11 -36
View File
@@ -592,7 +592,7 @@ export async function deactivate() {
TelemetryProxy.getInstance().shutdown()
}
async function openKiloInNewTab(
function openKiloInNewTab(
context: vscode.ExtensionContext,
connectionService: KiloConnectionService,
agentManagerProvider: AgentManagerProvider,
@@ -601,20 +601,16 @@ async function openKiloInNewTab(
remoteService: RemoteStatusService,
autoApprove: ReturnType<typeof registerToggleAutoApprove>,
) {
const lastCol = Math.max(...vscode.window.visibleTextEditors.map((e) => e.viewColumn || 0), 0)
const hasVisibleEditors = vscode.window.visibleTextEditors.length > 0
if (!hasVisibleEditors) {
await vscode.commands.executeCommand("workbench.action.newGroupRight")
}
const targetCol = hasVisibleEditors ? Math.max(lastCol + 1, 1) : vscode.ViewColumn.Two
const panel = vscode.window.createWebviewPanel("kilo-code.new.TabPanel", EXTENSION_DISPLAY_NAME, targetCol, {
enableScripts: true,
retainContextWhenHidden: true,
localResourceRoots: [context.extensionUri],
})
const panel = vscode.window.createWebviewPanel(
"kilo-code.new.TabPanel",
EXTENSION_DISPLAY_NAME,
vscode.ViewColumn.Active,
{
enableScripts: true,
retainContextWhenHidden: true,
localResourceRoots: [context.extensionUri],
},
)
panel.iconPath = {
light: vscode.Uri.joinPath(context.extensionUri, "assets", "icons", "kilo-light.svg"),
@@ -636,11 +632,6 @@ async function openKiloInNewTab(
tabProvider.resolveWebviewPanel(panel)
tabPanels.set(panel, tabProvider)
// Wait for the new panel to become active before locking the editor group.
// This avoids the race where VS Code hasn't switched focus yet.
await waitForWebviewPanelToBeActive(panel)
await vscode.commands.executeCommand("workbench.action.lockEditorGroup")
panel.onDidDispose(
() => {
console.log("[Kilo New] Tab panel disposed")
@@ -671,19 +662,3 @@ function ensureCommandsSkipShell(commands: string[]): void {
if (missing.length === 0) return
config.update("commandsToSkipShell", [...existing, ...missing], target)
}
function waitForWebviewPanelToBeActive(panel: vscode.WebviewPanel): Promise<void> {
if (panel.active) {
return Promise.resolve()
}
return new Promise((resolve) => {
const disposable = panel.onDidChangeViewState((event) => {
if (!event.webviewPanel.active) {
return
}
disposable.dispose()
resolve()
})
})
}
@@ -16,6 +16,7 @@ const PKG_JSON_FILE = path.join(ROOT, "package.json")
const SRC_DIR = path.join(ROOT, "src")
const EXTENSION_FILE = path.join(ROOT, "src/extension.ts")
const KILO_PROVIDER_FILE = path.join(ROOT, "src/KiloProvider.ts")
const SETTINGS_PROVIDER_FILE = path.join(ROOT, "src/SettingsEditorProvider.ts")
const VSCODE_HOST_FILE = path.join(ROOT, "src/agent-manager/vscode-host.ts")
function sliceBlock(source: string, start: number): string {
@@ -202,6 +203,32 @@ describe("Extension — KiloProvider handler wiring", () => {
})
})
describe("Extension — editor panel placement", () => {
const ext = fs.readFileSync(EXTENSION_FILE, "utf-8")
const settings = fs.readFileSync(SETTINGS_PROVIDER_FILE, "utf-8")
it("opens Kilo as a tab in the active editor group", () => {
const fn = ext.indexOf("function openKiloInNewTab")
expect(fn, "openKiloInNewTab must exist").toBeGreaterThan(-1)
const body = sliceBlock(ext, fn)
expect(body).toContain("vscode.ViewColumn.Active")
expect(body).not.toContain("visibleTextEditors")
expect(body).not.toContain("workbench.action.newGroupRight")
expect(body).not.toContain("workbench.action.lockEditorGroup")
})
it("opens and reveals Settings in the active editor group", () => {
const fn = settings.indexOf("openPanel(view")
expect(fn, "SettingsEditorProvider.openPanel must exist").toBeGreaterThan(-1)
const body = sliceBlock(settings, fn)
expect(body).toContain("existing.reveal(vscode.ViewColumn.Active)")
expect(body.match(/vscode\.ViewColumn\.Active/g)).toHaveLength(2)
expect(body).not.toContain("vscode.ViewColumn.One")
})
})
// ---------------------------------------------------------------------------
// KiloProvider — continueInWorktree error fallback
//