Порівняти коміти

...
Автор SHA1 Повідомлення Дата
l0ng-ai 04696c00c6 feat(layout): Restore Current Layout and Save Changes in Current Layout
Restore Current Layout applies the active saved tool window layout again,
or the default layout when none is active; Shift+F12 in the IntelliJ keymaps
now runs it. Save Changes in Current Layout stores the current windows into
the active layout. Both are in Window > Tool Window Layouts.
2026-11-15 01:27:13 +08:00
11 змінених файлів з 87 додано та 4 видалено

No files matched your search

+5
Переглянути файл
@@ -799,6 +799,9 @@ pub fn spec(os: Os) -> Vec<Entry> {
"toolWindowLayouts",
"Tool Window Layouts",
vec![
act("layout.saveCurrent", "Save Changes in Current Layout"),
act("layout.restoreCurrent", "Restore Current Layout"),
SEP,
act("layout.save", "Save Current Layout as…"),
act("layout.restoreDefault", "Restore Default Layout"),
SEP,
@@ -2318,6 +2321,8 @@ mod tests {
"view.quickSwitchScheme",
"code.cleanup",
"runAnything.show",
"layout.saveCurrent",
"layout.restoreCurrent",
"layout.save",
"layout.restoreDefault",
"layout.rename",
+1 -1
Переглянути файл
@@ -78,7 +78,7 @@ describe("IDEA keymap parity", () => {
["editor.nextSplitter", ["Alt+Tab"], ["Alt+Tab"]],
["toolwindow.resizeLeft", ["Ctrl+Alt+Left"], ["Ctrl+Alt+Shift+Left"]],
["toolwindow.closeContent", ["Meta+W", "Ctrl+Shift+F4"], ["Ctrl+F4", "Ctrl+Shift+F4"]],
["layout.restoreDefault", ["Shift+F12"], ["Shift+F12"]],
["layout.restoreCurrent", ["Shift+F12"], ["Shift+F12"]],
["workbench.stopBackgroundProcesses", ["Meta+Shift+F2"], ["Ctrl+Shift+F2"]],
["navigate.back", ["Meta+[", "Meta+Alt+Left", "Button4", "SwipeRight"], ["Ctrl+Alt+Left", "Button4"]],
["navigate.forward", ["Meta+]", "Meta+Alt+Right", "Button5", "SwipeLeft"], ["Ctrl+Alt+Right", "Button5"]],
+2 -1
Переглянути файл
@@ -237,7 +237,8 @@ export const intellijMacos: Record<string, string[]> = {
"toolwindow.resizeRight": ["Ctrl+Alt+Right"],
"toolwindow.resizeUp": ["Ctrl+Alt+Up"],
"toolwindow.resizeDown": ["Ctrl+Alt+Down"],
"layout.restoreDefault": ["Shift+F12"],
"layout.restoreCurrent": ["Shift+F12"],
"layout.restoreDefault": [],
"toolwindow.jumpToLast": ["F12"],
"toolwindow.hideActive": ["Shift+Escape"],
"toolwindow.focusEditor": ["Escape"],
+2 -1
Переглянути файл
@@ -234,7 +234,8 @@ export const intellijWindows: Record<string, string[]> = {
"toolwindow.terminal": ["Alt+F12"],
"toolwindow.hideAll": ["Ctrl+Shift+F12"],
"toolwindow.maximize": ["Ctrl+Shift+'"],
"layout.restoreDefault": ["Shift+F12"],
"layout.restoreCurrent": ["Shift+F12"],
"layout.restoreDefault": [],
"toolwindow.jumpToLast": ["F12"],
"toolwindow.hideActive": ["Shift+Escape"],
"toolwindow.focusEditor": ["Escape"],
+1
Переглянути файл
@@ -65,6 +65,7 @@ export const vscodeMacos: Record<string, string[]> = {
"toolwindow.resizeRight": [],
"toolwindow.resizeUp": [],
"toolwindow.resizeDown": [],
"layout.restoreCurrent": [],
"layout.restoreDefault": [],
"workbench.stopBackgroundProcesses": [],
"navigate.typeHierarchy": [],
+2
Переглянути файл
@@ -457,6 +457,8 @@
"menu.runAnything.show": "Run Anything…",
"menu.localHistory.putLabel": "Put Label…",
"menu.toolWindowLayouts": "Tool Window Layouts",
"menu.layout.saveCurrent": "Save Changes in Current Layout",
"menu.layout.restoreCurrent": "Restore Current Layout",
"menu.layout.save": "Save Current Layout as…",
"menu.layout.restoreDefault": "Restore Default Layout",
"menu.layout.rename": "Rename Layout…",
+3
Переглянути файл
@@ -2390,6 +2390,9 @@
"Restart is only available in the desktop app": "只有桌面应用可以重启",
"Restore Default": "恢复默认值",
"Restore Default Layout": "恢复默认布局",
"Restore Current Layout": "恢复当前布局",
"Save Changes in Current Layout": "保存对当前布局的更改",
"Restores the active saved layout, or the default layout when none is active.": "恢复当前选中的已保存布局;没有选中的布局时恢复默认布局。",
"Restore Defaults": "恢复默认值",
"Restore Rows": "恢复行",
"Restore Size": "恢复大小",
+2
Переглянути файл
@@ -457,6 +457,8 @@
"menu.runAnything.show": "运行任何内容…",
"menu.localHistory.putLabel": "添加标签…",
"menu.toolWindowLayouts": "工具窗口布局",
"menu.layout.saveCurrent": "保存对当前布局的更改",
"menu.layout.restoreCurrent": "恢复当前布局",
"menu.layout.save": "将当前布局另存为…",
"menu.layout.restoreDefault": "恢复默认布局",
"menu.layout.rename": "重命名布局…",
+29 -1
Переглянути файл
@@ -10,8 +10,10 @@ import {
deleteLayout,
layoutNames,
renameLayout,
restoreCurrentLayout,
restoreDefaultLayout,
restoreLayout,
saveCurrentLayout,
saveLayout,
useToolWindowLayouts,
} from "./layouts";
@@ -93,6 +95,28 @@ function layoutActions(): Action[] {
if (name) restoreLayout(name);
},
},
{
id: "layout.restoreCurrent",
title: "Restore Current Layout",
description: "Restores the active saved layout, or the default layout when none is active.",
category: "Window",
keywords: ["tool window layout", "reset"],
when: "projectOpen",
run: () => {
exitDistractionFree();
restoreCurrentLayout();
},
},
{
id: "layout.saveCurrent",
title: "Save Changes in Current Layout",
category: "Window",
keywords: ["tool window layout", "store layout"],
when: "projectOpen && toolWindowLayoutActive",
run: () => {
saveCurrentLayout();
},
},
{
id: "layout.restoreDefault",
title: "Restore Default Layout",
@@ -175,7 +199,11 @@ export function installToolWindowActions(): () => void {
const unsubscribe = useContributions.subscribe((s, prev) => {
if (s.toolWindows !== prev.toolWindows) sync();
});
const publishLayouts = () => setContext("toolWindowLayoutsSaved", useToolWindowLayouts.getState().layouts.length > 0);
const publishLayouts = () => {
const { layouts, active } = useToolWindowLayouts.getState();
setContext("toolWindowLayoutsSaved", layouts.length > 0);
setContext("toolWindowLayoutActive", !!active);
};
publishLayouts();
const unsubscribeLayouts = useToolWindowLayouts.subscribe(publishLayouts);
/** The window an Options menu names, else the active one. */
+26
Переглянути файл
@@ -43,6 +43,32 @@ beforeEach(() => {
afterEach(() => disposers.forEach((d) => d()));
describe("tool window layouts", () => {
it("restores the current layout, and saves changes into it", async () => {
setContext("projectOpen", true);
setToolWindowSize("bottom", 400);
saveLayout("Custom 1");
setToolWindowSize("bottom", 200);
await executeAction("layout.restoreCurrent");
expect(useToolWindowLayout.getState().sizes.bottom).toBe(400);
expect(getContext().toolWindowLayoutActive).toBe(true);
setToolWindowSize("bottom", 300);
await executeAction("layout.saveCurrent");
setToolWindowSize("bottom", 200);
await executeAction("layout.restoreCurrent");
expect(useToolWindowLayout.getState().sizes.bottom).toBe(300);
expect(layoutNames()).toEqual(["Custom 1"]);
// With no active layout it is the default one.
restoreDefaultLayout();
expect(getContext().toolWindowLayoutActive).toBe(false);
const defaultBottom = useToolWindowLayout.getState().sizes.bottom;
setToolWindowSize("bottom", 350);
await executeAction("layout.restoreCurrent");
expect(useToolWindowLayout.getState().sizes.bottom).toBe(defaultBottom);
setContext("projectOpen", false);
});
it("saves and restores visible windows and sizes by name", () => {
showToolWindow("structure");
showToolWindow("terminal");
+14
Переглянути файл
@@ -72,6 +72,20 @@ export function restoreLayout(name: string): boolean {
return true;
}
/** Restore Current Layout: the active saved layout again, or the default one when none is active. */
export function restoreCurrentLayout() {
const { active } = useToolWindowLayouts.getState();
if (!active || !restoreLayout(active)) restoreDefaultLayout();
}
/** Save Changes in Current Layout: the active saved layout takes the windows as they are now. */
export function saveCurrentLayout(): boolean {
const { active } = useToolWindowLayouts.getState();
if (!active) return false;
saveLayout(active);
return true;
}
export function restoreDefaultLayout() {
applyToolWindowLayout(defaultLayoutSnapshot());
write({ ...useToolWindowLayouts.getState(), active: null });