Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 7 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -328,25 +328,18 @@
"default": false,
"description": "Automatically reveal a new Pi chat tab when the extension activates. Previously open Pi session tabs are always restored."
},
"pi-on-code.newChatPanelLocation": {
"pi-on-code.chatPanelLocation": {
"type": "string",
"default": "panel",
"enum": ["panel", "splitPanel"],
"enumDescriptions": [
"Open brand-new Pi chats as tabs in the active editor group without splitting the editor area.",
"Open brand-new Pi chats in a new editor group split to the right of the active group."
"enum": [
"panel",
"splitPanel"
],
"description": "Where brand-new Pi chats open in the editor."
},
"pi-on-code.chatPanelLocation": {
"type": "string",
"default": "splitPanel",
"enum": ["panel", "splitPanel"],
"enumDescriptions": [
"Open resumed/forked Pi chats as tabs in the active editor group without splitting the editor area.",
"Open resumed/forked Pi chats in a new editor group split to the right of the active group (historical default)."
"Open Pi chats (new, resumed, and forked) as tabs in the active editor group without splitting the editor area.",
"Open Pi chats (new, resumed, and forked) in a new editor group split to the right of the active group."
],
"description": "Where resumed and forked Pi chats open in the editor."
"description": "Where Pi chats open in the editor: as a tab in the active group, or split to the right."
}
}
},
Expand Down
4 changes: 2 additions & 2 deletions src/chat-panel-location.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
* - `"panel"` — the chat opens as a tab in the active editor group; the editor
* area is never split for it.
* - `"splitPanel"` — the chat opens in a new editor group split to the right
* of the active group (historical default behavior).
* of the active group.
*/
export type ChatPanelLocation = "panel" | "splitPanel";

export const DEFAULT_CHAT_PANEL_LOCATION: ChatPanelLocation = "splitPanel";
export const DEFAULT_CHAT_PANEL_LOCATION: ChatPanelLocation = "panel";

export function parseChatPanelLocation(raw: unknown): ChatPanelLocation {
return raw === "panel" || raw === "splitPanel"
Expand Down
2 changes: 1 addition & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1971,7 +1971,7 @@ function addSession(context: vscode.ExtensionContext, cwd = getWorkspaceCwd()):
void saveOpenSessionPaths();
};
setActiveSession(sw);
void sw.webviewPanel.show(chatShowColumn("newChatPanelLocation"));
void sw.webviewPanel.show(chatShowColumn("chatPanelLocation"));
void initSessionInBackground(context, sw, { fresh: true });
}

Expand Down
49 changes: 24 additions & 25 deletions src/test/chat-panel-location.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,49 @@ import {
} from "../chat-panel-location.js";

suite("Chat panel location", () => {
test("defaults to splitPanel for missing or invalid values", () => {
assert.strictEqual(DEFAULT_CHAT_PANEL_LOCATION, "splitPanel");
assert.strictEqual(parseChatPanelLocation(undefined), "splitPanel");
assert.strictEqual(parseChatPanelLocation("sidebar-left"), "splitPanel");
assert.strictEqual(parseChatPanelLocation(42), "splitPanel");
test("defaults to panel for missing or invalid values", () => {
assert.strictEqual(DEFAULT_CHAT_PANEL_LOCATION, "panel");
assert.strictEqual(parseChatPanelLocation(undefined), "panel");
assert.strictEqual(parseChatPanelLocation("sidebar-left"), "panel");
assert.strictEqual(parseChatPanelLocation(42), "panel");
});

test("accepts the two documented locations", () => {
test("accepts the two editor placements", () => {
assert.strictEqual(parseChatPanelLocation("panel"), "panel");
assert.strictEqual(parseChatPanelLocation("splitPanel"), "splitPanel");
});

test("publishes new (panel) and resume/fork (splitPanel) properties", () => {
test("publishes exactly one chatPanelLocation property defaulting to panel", () => {
const manifest = JSON.parse(
readFileSync(new URL("../../package.json", import.meta.url), "utf8"),
) as {
contributes: {
configuration: {
properties: Record<string, {
default: unknown;
enum?: unknown[];
enumDescriptions?: unknown[];
}>;
properties: Record<string, { default?: unknown; enum?: unknown[] }>;
};
};
};
const newProp = manifest.contributes.configuration.properties["pi-on-code.newChatPanelLocation"];
const resumeProp = manifest.contributes.configuration.properties["pi-on-code.chatPanelLocation"];
assert.ok(newProp, "pi-on-code.newChatPanelLocation property is missing");
assert.strictEqual(newProp.default, "panel");
assert.deepStrictEqual(newProp.enum, ["panel", "splitPanel"]);
assert.ok(resumeProp, "pi-on-code.chatPanelLocation property is missing");
assert.strictEqual(resumeProp.default, "splitPanel");
assert.deepStrictEqual(resumeProp.enum, ["panel", "splitPanel"]);
const properties = manifest.contributes.configuration.properties;
const property = properties["pi-on-code.chatPanelLocation"];
assert.ok(property, "pi-on-code.chatPanelLocation property is missing");
assert.strictEqual(property.default, "panel");
assert.deepStrictEqual(property.enum, ["panel", "splitPanel"]);
assert.ok(
!("pi-on-code.newChatPanelLocation" in properties),
"the duplicate newChatPanelLocation property must be gone",
);
});

test("routes new chats through newChatPanelLocation and resumes/forks through chatPanelLocation", () => {
test("new, resumed, and forked chats all follow chatPanelLocation", () => {
const extension = readFileSync(
new URL("../../src/extension.ts", import.meta.url),
"utf8",
);
assert.match(extension, /function chatShowColumn\(key: string\)/);
assert.match(extension, /sw\.webviewPanel\.show\(chatShowColumn\("newChatPanelLocation"\)\)/);
assert.match(extension, /newSw\.webviewPanel\.show\(chatShowColumn\("chatPanelLocation"\)\)/);
assert.match(extension, /await sw\.webviewPanel\.show\(chatShowColumn\("chatPanelLocation"\)\)/);
assert.match(extension, /void sw\.webviewPanel\.show\(chatShowColumn\("chatPanelLocation"\)\);/);
assert.match(extension, /void newSw\.webviewPanel\.show\(chatShowColumn\("chatPanelLocation"\)\);/);
assert.match(extension, /await sw\.webviewPanel\.show\(chatShowColumn\("chatPanelLocation"\)\);/);
assert.doesNotMatch(extension, /newChatPanelLocation/);
const occurrences = extension.match(/chatShowColumn\("chatPanelLocation"\)/g)?.length ?? 0;
assert.strictEqual(occurrences, 3, "new, resume, and fork must share the single setting");
});
});
Loading