mirror of
https://gitee.com/zhangsken/opencode.git
synced 2026-10-16 10:30:01 +08:00
feat(plugin): decompose tab controls (#48129)
Co-authored-by: vimtor <36263538+vimtor@users.noreply.github.com> Co-authored-by: Victor Navarro <vn4varro@gmail.com>
This commit is contained in:
committed by
GitHub
parent
c0cb1c7a91
commit
be2582f316
@@ -487,10 +487,12 @@ export interface UI {
|
||||
readonly attention: boolean
|
||||
readonly unread?: "activity" | "error"
|
||||
}[]
|
||||
/** Opens (or focuses) a tab for a session, adding it when not already open. Returns false when tabs are disabled. */
|
||||
/** Opens a tab for a session without focusing it. Returns false when tabs are disabled. */
|
||||
open(sessionID: string): boolean
|
||||
/** Focuses an already-open tab and returns false when it is not open. */
|
||||
/** Opens a tab when needed, then focuses it. Returns false when tabs are disabled. */
|
||||
focus(sessionID: string): boolean
|
||||
/** Moves an open tab to an index and returns false when it is not open. */
|
||||
move(sessionID: string, index: number): boolean
|
||||
/** Closes an open tab, or the active tab when omitted, and returns false when no tab matched. */
|
||||
close(sessionID?: string): boolean
|
||||
}
|
||||
|
||||
@@ -395,6 +395,15 @@ export const { use: useSessionTabs, provider: SessionTabsProvider } = createSimp
|
||||
if (!enabled()) return
|
||||
route.navigate({ type: "session", sessionID: root(sessionID) })
|
||||
},
|
||||
open(sessionID: string) {
|
||||
if (!enabled()) return
|
||||
const session = root(sessionID)
|
||||
if (state().tabs.some((tab) => tab.sessionID === session)) return
|
||||
cancelledTabs.delete(session)
|
||||
update((draft) => {
|
||||
draft.tabs = openSessionTab(draft.tabs, { sessionID: session, title: title(session) })
|
||||
})
|
||||
},
|
||||
promote(sessionID: string) {
|
||||
if (!enabled()) return
|
||||
const session = root(sessionID)
|
||||
|
||||
@@ -206,15 +206,21 @@ export function createPluginContext(input: {
|
||||
}),
|
||||
open(sessionID) {
|
||||
if (!host.sessionTabs.enabled()) return false
|
||||
host.sessionTabs.select(sessionID)
|
||||
host.sessionTabs.open(sessionID)
|
||||
return true
|
||||
},
|
||||
focus(sessionID) {
|
||||
if (!host.sessionTabs.enabled()) return false
|
||||
if (!host.sessionTabs.tabs().some((tab) => tab.sessionID === sessionID)) return false
|
||||
host.sessionTabs.select(sessionID)
|
||||
return true
|
||||
},
|
||||
move(sessionID, index) {
|
||||
if (!host.sessionTabs.enabled()) return false
|
||||
const target = host.data.session.root(sessionID)
|
||||
if (!host.sessionTabs.tabs().some((tab) => tab.sessionID === target)) return false
|
||||
host.sessionTabs.move(target, index)
|
||||
return true
|
||||
},
|
||||
close(sessionID) {
|
||||
if (!host.sessionTabs.enabled()) return false
|
||||
const target = sessionID ?? host.sessionTabs.current()
|
||||
|
||||
@@ -265,6 +265,23 @@ test("loads VCS metadata for each persisted tab location", async () => {
|
||||
}
|
||||
})
|
||||
|
||||
test("opens a background tab without changing the current session", async () => {
|
||||
const setup = await renderSessionTabs("first")
|
||||
|
||||
try {
|
||||
await wait(() => setup.tabs.current() === "first" && setup.tabs.tabs().some((tab) => tab.sessionID === "first"))
|
||||
setup.tabs.open("background")
|
||||
await wait(() => setup.tabs.tabs().some((tab) => tab.sessionID === "background"))
|
||||
|
||||
expect(setup.tabs.current()).toBe("first")
|
||||
expect(setup.tabs.isPreview("background")).toBe(false)
|
||||
setup.tabs.move("background", 0)
|
||||
await wait(() => setup.tabs.tabs()[0]?.sessionID === "background")
|
||||
} finally {
|
||||
await setup.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
test("loads location metadata when an open session moves", async () => {
|
||||
const destination = `${directory}/moved-worktree`
|
||||
const setup = await renderSessionTabs("first")
|
||||
|
||||
@@ -375,13 +375,15 @@ context.ui.router.navigate({ type: "home" })
|
||||
return unregister
|
||||
```
|
||||
|
||||
Tabs can be listed, opened, focused, and closed when session tabs are enabled.
|
||||
Tabs can be listed, opened, focused, moved, and closed when session tabs are enabled. `open` leaves focus unchanged;
|
||||
`focus` opens the tab when needed.
|
||||
|
||||
```ts
|
||||
if (context.ui.tabs.enabled()) {
|
||||
context.ui.tabs.open(sessionID)
|
||||
const tabs = context.ui.tabs.list()
|
||||
context.ui.tabs.open(backgroundSessionID)
|
||||
context.ui.tabs.focus(sessionID)
|
||||
const tabs = context.ui.tabs.list()
|
||||
context.ui.tabs.move(backgroundSessionID, tabs.length - 1)
|
||||
context.ui.tabs.close(sessionID)
|
||||
context.ui.tabs.close()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user