дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
feat(editor): Close read-only tabs and keep a preview tab open from the tab menu (#165)
The editor tab menu gains Close All Read-Only Tabs (shown when the group has unpinned read-only tabs) and Keep Tab Open (on a preview tab), which turns the preview into a regular tab.
Цей коміт міститься в:
1 джерело
e0af8ccce1
коміт
c7f75cb693
3 files changed
+29
No files matched your search
@@ -2,6 +2,7 @@ import { afterEach, describe, expect, it } from "vitest";
|
||||
import { EditorController, openFilePaths, useEditorStatus, useTabs } from "./controller";
|
||||
import { createMemoryBackend } from "./backend";
|
||||
import { initialTabsState } from "./model/tabs";
|
||||
import { useDocMeta } from "./model/document";
|
||||
import { resetDistractionFree, setDistractionFree } from "@/workbench/distractionFree";
|
||||
import { registerActions } from "@/platform/actions";
|
||||
import { useProject } from "@/platform/project";
|
||||
@@ -82,6 +83,24 @@ describe("EditorController", () => {
|
||||
expect(paths(first)).toEqual(["/p/a.ts", "/p/b.ts"]);
|
||||
});
|
||||
|
||||
it("closes read-only tabs and keeps a preview tab open from the tab menu", async () => {
|
||||
ctrl = new EditorController(createMemoryBackend({ "/p/a.ts": "", "/p/b.ts": "", "/p/c.ts": "" }));
|
||||
ctrl.start();
|
||||
await ctrl.openFile("/p/a.ts", { focus: false });
|
||||
await ctrl.openFile("/p/b.ts", { focus: false });
|
||||
await ctrl.openFile("/p/c.ts", { focus: false, preview: true });
|
||||
const pane = () => useTabs.getState().panes[useTabs.getState().activePane]!;
|
||||
const labels = () => resolveMenuItems(ctrl!.tabMenu(pane().id, pane().tabs[2]!)).map((i) => i.label);
|
||||
expect(labels()).toContain("Keep Tab Open");
|
||||
expect(labels()).not.toContain("Close All Read-Only Tabs");
|
||||
ctrl.keepTab(pane().id, pane().tabs[2]!.id);
|
||||
expect(pane().tabs[2]!.preview).toBe(false);
|
||||
useDocMeta.setState({ "/p/b.ts": { ...useDocMeta.getState()["/p/b.ts"]!, readOnly: true } });
|
||||
expect(labels()).toContain("Close All Read-Only Tabs");
|
||||
ctrl.closeReadOnly(pane().id);
|
||||
expect(pane().tabs.map((t) => t.input.path)).toEqual(["/p/a.ts", "/p/c.ts"]);
|
||||
});
|
||||
|
||||
it("reopens the LightEdit files the next time a window switches to LightEdit", async () => {
|
||||
ctrl = new EditorController(createMemoryBackend({ "/x/a.txt": "a", "/y/b.md": "b" }));
|
||||
ctrl.start();
|
||||
|
||||
@@ -915,6 +915,10 @@ export class EditorController implements SlotHost {
|
||||
};
|
||||
this.apply((s) => closeUnmodified(s, paneId, modified));
|
||||
}
|
||||
closeReadOnly(paneId: string) {
|
||||
const writable = (t: Tab) => !t.input.path || !useDocMeta.getState()[t.input.path]?.readOnly;
|
||||
this.apply((s) => closeUnmodified(s, paneId, writable));
|
||||
}
|
||||
/** Reload from Disk: re-reads the open, unmodified documents of `paths`. */
|
||||
async reloadFromDisk(paths: string[]) {
|
||||
for (const path of paths) {
|
||||
@@ -1189,8 +1193,12 @@ export class EditorController implements SlotHost {
|
||||
...(tabs.some((t) => t.pinned)
|
||||
? ([{ label: "Close All but Pinned", run: () => this.closeAll(paneId, true) }] as MenuItem[])
|
||||
: []),
|
||||
...(tabs.some((t) => !t.pinned && !!t.input.path && useDocMeta.getState()[t.input.path]?.readOnly)
|
||||
? ([{ label: "Close All Read-Only Tabs", run: () => this.closeReadOnly(paneId) }] as MenuItem[])
|
||||
: []),
|
||||
{ kind: "separator" },
|
||||
{ label: tab.pinned ? "Unpin Tab" : "Pin Tab", icon: "pin", run: () => this.togglePin(paneId, tab.id) },
|
||||
...(tab.preview ? ([{ label: "Keep Tab Open", run: () => this.keepTab(paneId, tab.id) }] as MenuItem[]) : []),
|
||||
{ kind: "separator" },
|
||||
{ label: "Split and Move Right", run: () => this.moveTabToSplit(paneId, tab.id, paneId, "right") },
|
||||
{ label: "Split and Move Down", run: () => this.moveTabToSplit(paneId, tab.id, paneId, "bottom") },
|
||||
|
||||
@@ -280,6 +280,7 @@
|
||||
"Cloned, but the project could not be opened": "已克隆,但无法打开项目",
|
||||
"Cloning requires the desktop app": "克隆需要桌面应用",
|
||||
"Close": "关闭",
|
||||
"Close All Read-Only Tabs": "关闭所有只读标签页",
|
||||
"Close All Tabs": "关闭所有标签页",
|
||||
"Close All but Pinned": "关闭除已固定外的所有标签页",
|
||||
"Close Annotations": "关闭注解",
|
||||
@@ -954,6 +955,7 @@
|
||||
"Jump to Source": "跳转到源代码",
|
||||
"Just Restart": "仅重启",
|
||||
"Keep": "保留",
|
||||
"Keep Tab Open": "保持标签页打开",
|
||||
"Keep Column": "保留列",
|
||||
"Keep index": "保留索引",
|
||||
"Keep local history for": "本地历史记录保留时长",
|
||||
|
||||
Reference in new issue
Заблокувати користувача