Skip to content

Commit d61147b

Browse files
committed
Persist terminal tab order
1 parent 1b378ea commit d61147b

1 file changed

Lines changed: 61 additions & 3 deletions

File tree

packages/app/src/context/terminal.tsx

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createStore, produce } from "solid-js/store"
22
import { createSimpleContext } from "@opencode-ai/ui/context"
3-
import { batch, createMemo, createRoot, onCleanup } from "solid-js"
3+
import { batch, createEffect, createMemo, createRoot, onCleanup } from "solid-js"
44
import { useParams } from "@solidjs/router"
55
import { useSDK } from "./sdk"
66
import { Persist, persisted } from "@/utils/persist"
@@ -9,6 +9,7 @@ export type LocalPTY = {
99
id: string
1010
title: string
1111
titleNumber: number
12+
order?: number
1213
rows?: number
1314
cols?: number
1415
buffer?: string
@@ -73,13 +74,48 @@ function createTerminalSession(sdk: ReturnType<typeof useSDK>, dir: string, id:
7374
}),
7475
)
7576

77+
const withSequentialOrder = (list: LocalPTY[]) =>
78+
list.map((item, index) => (item.order === index ? item : { ...item, order: index }))
79+
80+
const normalizeOrder = () => {
81+
const current = store.all
82+
if (current.length === 0) return
83+
const indexed = current.map((item, index) => ({
84+
item,
85+
index,
86+
order: item.order ?? index,
87+
}))
88+
const sorted = [...indexed].sort((a, b) => {
89+
if (a.order !== b.order) return a.order - b.order
90+
return a.index - b.index
91+
})
92+
const next = sorted.map((entry, index) =>
93+
entry.item.order === index ? entry.item : { ...entry.item, order: index },
94+
)
95+
const changed =
96+
next.length !== current.length || next.some((item, index) => item.id !== current[index]?.id || item !== current[index])
97+
if (changed) {
98+
setStore("all", next)
99+
}
100+
}
101+
102+
let normalized = false
103+
createEffect(() => {
104+
if (!ready()) return
105+
if (normalized) return
106+
if (store.all.length === 0) return
107+
normalized = true
108+
normalizeOrder()
109+
})
110+
76111
const removeLocal = (id: string) => {
77112
batch(() => {
78113
const current = store.all
79114
const index = current.findIndex((item) => item.id === id)
115+
const nextAll = withSequentialOrder(current.filter((x) => x.id !== id))
80116
setStore(
81117
"all",
82-
current.filter((x) => x.id !== id),
118+
nextAll,
83119
)
84120
if (store.active === id) {
85121
const next = index >= 0 ? current[index + 1] : undefined
@@ -105,7 +141,21 @@ function createTerminalSession(sdk: ReturnType<typeof useSDK>, dir: string, id:
105141

106142
return {
107143
ready,
108-
all: createMemo(() => Object.values(store.all)),
144+
all: createMemo(() => {
145+
const current = store.all
146+
if (current.length <= 1) return current
147+
const indexed = current.map((item, index) => ({
148+
item,
149+
index,
150+
order: item.order ?? index,
151+
}))
152+
return indexed
153+
.sort((a, b) => {
154+
if (a.order !== b.order) return a.order - b.order
155+
return a.index - b.index
156+
})
157+
.map((entry) => entry.item)
158+
}),
109159
active: createMemo(() => store.active),
110160
removeLocal,
111161
markError,
@@ -122,6 +172,9 @@ function createTerminalSession(sdk: ReturnType<typeof useSDK>, dir: string, id:
122172
nextNumber++
123173
}
124174

175+
const nextOrder =
176+
store.all.reduce((max, pty, index) => Math.max(max, pty.order ?? index), -1) + 1
177+
125178
sdk.client.pty
126179
.create({ title: `Terminal ${nextNumber}` })
127180
.then((pty) => {
@@ -133,6 +186,7 @@ function createTerminalSession(sdk: ReturnType<typeof useSDK>, dir: string, id:
133186
id,
134187
title: pty.data?.title ?? "Terminal",
135188
titleNumber: nextNumber,
189+
order: nextOrder,
136190
status: "running",
137191
retryCount: 0,
138192
},
@@ -263,6 +317,10 @@ function createTerminalSession(sdk: ReturnType<typeof useSDK>, dir: string, id:
263317
"all",
264318
produce((all) => {
265319
all.splice(to, 0, all.splice(index, 1)[0])
320+
for (let i = 0; i < all.length; i++) {
321+
if (all[i].order === i) continue
322+
all[i] = { ...all[i], order: i }
323+
}
266324
}),
267325
)
268326
},

0 commit comments

Comments
 (0)