Pārlūkot izejas kodu

feat(app): sync embedded terminal theme (#37931)

Luke Parker 3 nedēļas atpakaļ
vecāks
revīzija
43e472bba7

+ 2 - 2
bun.lock

@@ -65,7 +65,7 @@
         "diff": "catalog:",
         "effect": "catalog:",
         "fuzzysort": "catalog:",
-        "ghostty-web": "github:anomalyco/ghostty-web#0dcf95815d9200761bc543f27df09c9e4232032a",
+        "ghostty-web": "github:anomalyco/ghostty-web#83c0a07b8628b748aed073b232cb4b52a6ca11c1",
         "luxon": "catalog:",
         "marked": "catalog:",
         "marked-shiki": "catalog:",
@@ -3845,7 +3845,7 @@
 
     "get-tsconfig": ["get-tsconfig@4.14.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA=="],
 
-    "ghostty-web": ["ghostty-web@github:anomalyco/ghostty-web#0dcf958", {}, "anomalyco-ghostty-web-0dcf958", "sha512-KK0mXG+XVoIq+bc/KgeypxvfkN06r+t+OzSECwRh2nTJqBLKVHSaE9P6tP3IbjIqU6LJnOIQafnEgFUKpKR63w=="],
+    "ghostty-web": ["ghostty-web@github:anomalyco/ghostty-web#83c0a07", {}, "anomalyco-ghostty-web-83c0a07", "sha512-Lf2v1agHkVUpMpHBWWuCZrhOEmcwwin5/Hboc9rZwQ7/CKkIh5rU1r1CvfLlhkMoFv+ed8z52RZ8hkzGZZj3MQ=="],
 
     "giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="],
 

+ 1 - 1
packages/app/package.json

@@ -81,7 +81,7 @@
     "diff": "catalog:",
     "effect": "catalog:",
     "fuzzysort": "catalog:",
-    "ghostty-web": "github:anomalyco/ghostty-web#0dcf95815d9200761bc543f27df09c9e4232032a",
+    "ghostty-web": "github:anomalyco/ghostty-web#83c0a07b8628b748aed073b232cb4b52a6ca11c1",
     "luxon": "catalog:",
     "marked": "catalog:",
     "marked-shiki": "catalog:",

+ 8 - 0
packages/app/src/addons/serialize.test.ts

@@ -37,6 +37,14 @@ function writeAndWait(term: Terminal, data: string): Promise<void> {
 }
 
 describe("SerializeAddon", () => {
+  test("preserves color scheme reporting mode", async () => {
+    const { term, addon } = createTerminal()
+    await writeAndWait(term, "\x1b[?2031h")
+
+    expect(addon.serialize().startsWith("\x1b[?2031h")).toBe(true)
+    expect(addon.serialize({ excludeModes: true }).startsWith("\x1b[?2031h")).toBe(false)
+  })
+
   describe("ANSI color preservation", () => {
     test("should preserve text attributes (bold, italic, underline)", async () => {
       const { term, addon } = createTerminal()

+ 9 - 1
packages/app/src/addons/serialize.ts

@@ -89,6 +89,13 @@ const getTerminalBuffers = (value: ITerminalCore): TerminalBuffers | undefined =
   return { active, normal, alternate }
 }
 
+const getTerminalMode = (value: ITerminalCore, mode: number) => {
+  if (!isRecord(value)) return false
+  const terminal = value.wasmTerm
+  if (!isRecord(terminal) || typeof terminal.getMode !== "function") return false
+  return terminal.getMode(mode) === true
+}
+
 // ============================================================================
 // Types
 // ============================================================================
@@ -544,7 +551,8 @@ export class SerializeAddon implements ITerminalAddon {
       return ""
     }
 
-    let content = options?.range
+    let content = !options?.excludeModes && getTerminalMode(this._terminal, 2031) ? "\u001b[?2031h" : ""
+    content += options?.range
       ? this._serializeBufferByRange(normalBuffer, options.range, true)
       : this._serializeBufferByScrollback(normalBuffer, options?.scrollback)
 

+ 10 - 1
packages/app/src/components/terminal.tsx

@@ -292,7 +292,12 @@ export const Terminal = (props: TerminalProps) => {
 
   const scheduleSize = (cols: number, rows: number) => {
     if (disposed) return
-    if (lastSize?.cols === cols && lastSize?.rows === rows) return
+    if (lastSize?.cols === cols && lastSize?.rows === rows) {
+      pendingSize = undefined
+      if (sizeTimer !== undefined) clearTimeout(sizeTimer)
+      sizeTimer = undefined
+      return
+    }
 
     pendingSize = { cols, rows }
 
@@ -317,8 +322,10 @@ export const Terminal = (props: TerminalProps) => {
 
   createEffect(() => {
     const colors = terminalColors()
+    const mode = theme.mode() === "dark" ? "dark" : "light"
     if (!term) return
     setOptionIfSupported(term, "theme", colors)
+    setOptionIfSupported(term, "colorScheme", mode)
   })
 
   createEffect(() => {
@@ -396,6 +403,7 @@ export const Terminal = (props: TerminalProps) => {
       }
       _ghostty = g
       term = t
+      setOptionIfSupported(t, "colorScheme", theme.mode() === "dark" ? "dark" : "light")
       output = terminalWriter((data, done) =>
         t.write(data, () => {
           done?.()
@@ -595,6 +603,7 @@ export const Terminal = (props: TerminalProps) => {
           tries = 0
           local.onConnect?.()
           scheduleSize(t.cols, t.rows)
+          if (t.getMode(2031)) t.write("\x1b[?996n")
         }
 
         const handleMessage = (event: MessageEvent) => {

+ 4 - 1
packages/core/src/pty/pty.node.ts

@@ -4,7 +4,10 @@ import type { Opts, Proc } from "./pty"
 export type { Disp, Exit, Opts, Proc } from "./pty"
 
 export function spawn(file: string, args: string[], opts: Opts): Proc {
-  const proc = pty.spawn(file, args, opts)
+  const proc = pty.spawn(file, args, {
+    ...opts,
+    ...(process.platform === "win32" ? { useConptyDll: true } : {}),
+  })
   return {
     pid: proc.pid,
     onData(listener) {