فهرست منبع

chore: generate

opencode-agent[bot] 3 ماه پیش
والد
کامیت
2c17e3a4db

+ 2 - 1
packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx

@@ -244,7 +244,8 @@ function AutoMethod(props: AutoMethodProps) {
       {
         key: "c",
         cmd: () => {
-          const code = props.authorization.instructions.match(/[A-Z0-9]{4}-[A-Z0-9]{4,5}/)?.[0] ?? props.authorization.url
+          const code =
+            props.authorization.instructions.match(/[A-Z0-9]{4}-[A-Z0-9]{4,5}/)?.[0] ?? props.authorization.url
           Clipboard.copy(code)
             .then(() => toast.show({ message: "Copied to clipboard", variant: "info" }))
             .catch(toast.error)

+ 8 - 7
packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx

@@ -60,12 +60,7 @@ import { useArgs } from "@tui/context/args"
 import { Flag } from "@opencode-ai/core/flag/flag"
 import { type WorkspaceStatus } from "../workspace-label"
 import { useCommandPalette } from "../../context/command-palette"
-import {
-  useBindings,
-  useCommandShortcut,
-  useLeaderActive,
-  useOpencodeKeymap,
-} from "../../keymap"
+import { useBindings, useCommandShortcut, useLeaderActive, useOpencodeKeymap } from "../../keymap"
 import { useTuiConfig } from "../../context/tui-config"
 
 export type PromptProps = {
@@ -890,7 +885,13 @@ export function Prompt(props: PromptProps) {
       target: inputTarget,
       enabled: (() => {
         cursorVersion()
-        return inputTarget() !== undefined && !props.disabled && store.mode === "normal" && !auto()?.visible && input?.visualCursor.offset === 0
+        return (
+          inputTarget() !== undefined &&
+          !props.disabled &&
+          store.mode === "normal" &&
+          !auto()?.visible &&
+          input?.visualCursor.offset === 0
+        )
       })(),
       bindings: [
         {

+ 12 - 2
packages/opencode/src/cli/cmd/tui/config/legacy-keymap-transform.ts

@@ -46,7 +46,12 @@ const inputCommands = {
   input_select_all: "input.select.all",
 } as const satisfies Partial<Record<keyof LegacyKeybinds, string>>
 
-function add(config: SectionsConfig, section: KeymapSection, command: string, binding: BindingValue<Renderable, KeyEvent> | undefined) {
+function add(
+  config: SectionsConfig,
+  section: KeymapSection,
+  command: string,
+  binding: BindingValue<Renderable, KeyEvent> | undefined,
+) {
   if (binding === undefined) return
   config[section] ??= {}
   config[section][command] = binding
@@ -154,7 +159,12 @@ export function create(keybinds: LegacyKeybinds): KeymapConfigInput {
   add(config, "dialog_select", "dialog.select.submit", keybinds["dialog.select.submit"])
   add(config, "dialog_actions", "dialog.action.delete", combineBindings(keybinds.stash_delete, keybinds.session_delete))
   add(config, "dialog_actions", "dialog.action.rename", keybinds.session_rename)
-  add(config, "dialog_actions", "dialog.action.toggle", combineBindings(keybinds["dialog.mcp.toggle"], keybinds["plugins.toggle"]))
+  add(
+    config,
+    "dialog_actions",
+    "dialog.action.toggle",
+    combineBindings(keybinds["dialog.mcp.toggle"], keybinds["plugins.toggle"]),
+  )
   add(config, "model", "model.dialog.provider", keybinds.model_provider_list)
   add(config, "model", "model.dialog.favorite", keybinds.model_favorite_toggle)
 

+ 6 - 1
packages/opencode/src/cli/cmd/tui/config/tui-schema.ts

@@ -293,7 +293,12 @@ export function keymapBindingDefaults(input: { section: string; binding: Readonl
 export const KeymapConfig = z
   .object({
     leader: z.string().prefault("ctrl+x"),
-    leader_timeout: z.number().int().positive().prefault(KeymapLeaderTimeoutDefault).describe("Leader key timeout in milliseconds"),
+    leader_timeout: z
+      .number()
+      .int()
+      .positive()
+      .prefault(KeymapLeaderTimeoutDefault)
+      .describe("Leader key timeout in milliseconds"),
     sections: KeymapSections,
   })
   .strict()

+ 1 - 6
packages/opencode/src/cli/cmd/tui/config/tui.ts

@@ -23,12 +23,7 @@ import * as Log from "@opencode-ai/core/util/log"
 import { ConfigVariable } from "@/config/variable"
 import { Npm } from "@opencode-ai/core/npm"
 import { LegacyKeymapTransform } from "./legacy-keymap-transform"
-import {
-  KeymapSectionNames,
-  keymapBindingDefaults,
-  type KeymapInfo,
-  type KeymapSection,
-} from "./tui-schema"
+import { KeymapSectionNames, keymapBindingDefaults, type KeymapInfo, type KeymapSection } from "./tui-schema"
 
 const log = Log.create({ service: "tui.config" })
 

+ 1 - 2
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

@@ -1101,8 +1101,7 @@ export function Session() {
                             >
                               <text fg={theme.textMuted}>{revert()!.reverted.length} message reverted</text>
                               <text fg={theme.textMuted}>
-                                <span style={{ fg: theme.text }}>{redoShortcut()}</span> or /redo to
-                                restore
+                                <span style={{ fg: theme.text }}>{redoShortcut()}</span> or /redo to restore
                               </text>
                               <Show when={revert()!.diffFiles?.length}>
                                 <box marginTop={1}>

+ 1 - 5
packages/opencode/src/cli/cmd/tui/routes/session/question.tsx

@@ -220,11 +220,7 @@ export function QuestionPrompt(props: { request: QuestionRequest }) {
           },
         },
         ...(confirm()
-          ? [
-              { key: "return", cmd: () => submit() },
-              { key: "escape", cmd: () => reject() },
-              ...sections.question,
-            ]
+          ? [{ key: "return", cmd: () => submit() }, { key: "escape", cmd: () => reject() }, ...sections.question]
           : [
               ...Array.from({ length: max }, (_, index) => ({
                 key: String(index + 1),

+ 18 - 10
packages/opencode/test/config/tui.test.ts

@@ -428,16 +428,20 @@ test("resolves semantic keymap sections", async () => {
   expect(config.keymap.sections.global.find((binding) => binding.cmd === "command.palette.show")?.key).toBe("alt+p")
   expect(config.keymap.sections.global.find((binding) => binding.cmd === "session.new")?.key).toBe("<leader>n")
   expect(config.keymap.sections.prompt.find((binding) => binding.cmd === "prompt.editor")?.key).toBe("ctrl+e")
-  expect(config.keymap.sections.autocomplete.find((binding) => binding.cmd === "prompt.autocomplete.next")?.key).toBe("ctrl+j")
-  expect(config.keymap.sections.dialog_actions.find((binding) => binding.cmd === "dialog.action.toggle")?.key).toBe("ctrl+t")
+  expect(config.keymap.sections.autocomplete.find((binding) => binding.cmd === "prompt.autocomplete.next")?.key).toBe(
+    "ctrl+j",
+  )
+  expect(config.keymap.sections.dialog_actions.find((binding) => binding.cmd === "dialog.action.toggle")?.key).toBe(
+    "ctrl+t",
+  )
   expect(config.keymap.sections.model.find((binding) => binding.cmd === "model.dialog.favorite")?.key).toBe("ctrl+f")
   expect(config.keymap.sections.plugins.find((binding) => binding.cmd === "plugin.dialog.install")?.key).toBe("shift+i")
   expect(config.keymap.pick("plugins", ["plugin.dialog.install"]).map((binding) => binding.cmd)).toEqual([
     "plugin.dialog.install",
   ])
-  expect(
-    (config.keymap.pick("plugins", ["plugin.dialog.install"])[0] as { group?: unknown } | undefined)?.group,
-  ).toBe("Plugins")
+  expect((config.keymap.pick("plugins", ["plugin.dialog.install"])[0] as { group?: unknown } | undefined)?.group).toBe(
+    "Plugins",
+  )
   expect(config.keymap.omit("plugins", ["plugin.dialog.install"]).map((binding) => binding.cmd)).toEqual([])
 })
 
@@ -477,8 +481,12 @@ test("legacy keybinds transform into semantic keymap sections", async () => {
   ])
   expect(config.keymap.sections.global.find((binding) => binding.cmd === "command.palette.show")?.key).toBe("alt+p")
   expect(config.keymap.sections.prompt.find((binding) => binding.cmd === "prompt.editor")?.key).toBe("ctrl+e")
-  expect(config.keymap.sections.autocomplete.find((binding) => binding.cmd === "prompt.autocomplete.next")?.key).toBe("ctrl+j")
-  expect(config.keymap.sections.dialog_actions.find((binding) => binding.cmd === "dialog.action.toggle")?.key).toBe("ctrl+t")
+  expect(config.keymap.sections.autocomplete.find((binding) => binding.cmd === "prompt.autocomplete.next")?.key).toBe(
+    "ctrl+j",
+  )
+  expect(config.keymap.sections.dialog_actions.find((binding) => binding.cmd === "dialog.action.toggle")?.key).toBe(
+    "ctrl+t",
+  )
   expect(config.keymap.sections.model.find((binding) => binding.cmd === "model.dialog.provider")?.key).toBe("ctrl+a")
   expect(config.keymap.sections.model.find((binding) => binding.cmd === "model.dialog.favorite")?.key).toBe("ctrl+f")
   expect(config.keymap.sections.plugins.find((binding) => binding.cmd === "plugin.dialog.install")?.key).toBe("shift+i")
@@ -486,9 +494,9 @@ test("legacy keybinds transform into semantic keymap sections", async () => {
   expect(config.keymap.pick("plugins", ["plugin.dialog.install"]).map((binding) => binding.cmd)).toEqual([
     "plugin.dialog.install",
   ])
-  expect(
-    (config.keymap.omit("plugins", ["plugin.dialog.install"])[0] as { group?: unknown } | undefined)?.group,
-  ).toBe("Plugins")
+  expect((config.keymap.omit("plugins", ["plugin.dialog.install"])[0] as { group?: unknown } | undefined)?.group).toBe(
+    "Plugins",
+  )
   expect(config.keymap.omit("plugins", ["plugin.dialog.install"]).map((binding) => binding.cmd)).toEqual([
     "plugins.list",
   ])

+ 5 - 5
packages/web/src/content/docs/keybinds.mdx

@@ -55,11 +55,11 @@ You do not need to use a leader key, but we recommend doing so.
 
 `keymap.sections` is grouped by semantic area. Each section contains command names and the key sequence that triggers them.
 
-| Field | Description |
-| ----- | ----------- |
-| `leader` | The key used by `<leader>` sequences. Defaults to `ctrl+x`. |
+| Field            | Description                                                                                         |
+| ---------------- | --------------------------------------------------------------------------------------------------- |
+| `leader`         | The key used by `<leader>` sequences. Defaults to `ctrl+x`.                                         |
 | `leader_timeout` | How long OpenCode waits for the next key after the leader key, in milliseconds. Defaults to `2000`. |
-| `sections` | A map of TUI areas to command bindings. |
+| `sections`       | A map of TUI areas to command bindings.                                                             |
 
 ---
 
@@ -310,7 +310,7 @@ On native Windows, the defaults for undo and terminal suspend are different for
 
 - `input.undo` defaults to `ctrl+z,ctrl+-,super+z` when it is not explicitly configured (the `ctrl+z` binding is added because Windows terminals do not support POSIX suspend).
 - `terminal.suspend` is disabled because native Windows terminals do not support POSIX suspend.
-:::
+  :::
 
 ---