chore: generate
This commit is contained in:
@@ -244,7 +244,8 @@ function AutoMethod(props: AutoMethodProps) {
|
|||||||
{
|
{
|
||||||
key: "c",
|
key: "c",
|
||||||
cmd: () => {
|
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)
|
Clipboard.copy(code)
|
||||||
.then(() => toast.show({ message: "Copied to clipboard", variant: "info" }))
|
.then(() => toast.show({ message: "Copied to clipboard", variant: "info" }))
|
||||||
.catch(toast.error)
|
.catch(toast.error)
|
||||||
|
|||||||
@@ -60,12 +60,7 @@ import { useArgs } from "@tui/context/args"
|
|||||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||||
import { type WorkspaceStatus } from "../workspace-label"
|
import { type WorkspaceStatus } from "../workspace-label"
|
||||||
import { useCommandPalette } from "../../context/command-palette"
|
import { useCommandPalette } from "../../context/command-palette"
|
||||||
import {
|
import { useBindings, useCommandShortcut, useLeaderActive, useOpencodeKeymap } from "../../keymap"
|
||||||
useBindings,
|
|
||||||
useCommandShortcut,
|
|
||||||
useLeaderActive,
|
|
||||||
useOpencodeKeymap,
|
|
||||||
} from "../../keymap"
|
|
||||||
import { useTuiConfig } from "../../context/tui-config"
|
import { useTuiConfig } from "../../context/tui-config"
|
||||||
|
|
||||||
export type PromptProps = {
|
export type PromptProps = {
|
||||||
@@ -890,7 +885,13 @@ export function Prompt(props: PromptProps) {
|
|||||||
target: inputTarget,
|
target: inputTarget,
|
||||||
enabled: (() => {
|
enabled: (() => {
|
||||||
cursorVersion()
|
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: [
|
bindings: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,7 +46,12 @@ const inputCommands = {
|
|||||||
input_select_all: "input.select.all",
|
input_select_all: "input.select.all",
|
||||||
} as const satisfies Partial<Record<keyof LegacyKeybinds, string>>
|
} 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
|
if (binding === undefined) return
|
||||||
config[section] ??= {}
|
config[section] ??= {}
|
||||||
config[section][command] = binding
|
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_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.delete", combineBindings(keybinds.stash_delete, keybinds.session_delete))
|
||||||
add(config, "dialog_actions", "dialog.action.rename", keybinds.session_rename)
|
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.provider", keybinds.model_provider_list)
|
||||||
add(config, "model", "model.dialog.favorite", keybinds.model_favorite_toggle)
|
add(config, "model", "model.dialog.favorite", keybinds.model_favorite_toggle)
|
||||||
|
|
||||||
|
|||||||
@@ -293,7 +293,12 @@ export function keymapBindingDefaults(input: { section: string; binding: Readonl
|
|||||||
export const KeymapConfig = z
|
export const KeymapConfig = z
|
||||||
.object({
|
.object({
|
||||||
leader: z.string().prefault("ctrl+x"),
|
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,
|
sections: KeymapSections,
|
||||||
})
|
})
|
||||||
.strict()
|
.strict()
|
||||||
|
|||||||
@@ -23,12 +23,7 @@ import * as Log from "@opencode-ai/core/util/log"
|
|||||||
import { ConfigVariable } from "@/config/variable"
|
import { ConfigVariable } from "@/config/variable"
|
||||||
import { Npm } from "@opencode-ai/core/npm"
|
import { Npm } from "@opencode-ai/core/npm"
|
||||||
import { LegacyKeymapTransform } from "./legacy-keymap-transform"
|
import { LegacyKeymapTransform } from "./legacy-keymap-transform"
|
||||||
import {
|
import { KeymapSectionNames, keymapBindingDefaults, type KeymapInfo, type KeymapSection } from "./tui-schema"
|
||||||
KeymapSectionNames,
|
|
||||||
keymapBindingDefaults,
|
|
||||||
type KeymapInfo,
|
|
||||||
type KeymapSection,
|
|
||||||
} from "./tui-schema"
|
|
||||||
|
|
||||||
const log = Log.create({ service: "tui.config" })
|
const log = Log.create({ service: "tui.config" })
|
||||||
|
|
||||||
|
|||||||
@@ -1101,8 +1101,7 @@ export function Session() {
|
|||||||
>
|
>
|
||||||
<text fg={theme.textMuted}>{revert()!.reverted.length} message reverted</text>
|
<text fg={theme.textMuted}>{revert()!.reverted.length} message reverted</text>
|
||||||
<text fg={theme.textMuted}>
|
<text fg={theme.textMuted}>
|
||||||
<span style={{ fg: theme.text }}>{redoShortcut()}</span> or /redo to
|
<span style={{ fg: theme.text }}>{redoShortcut()}</span> or /redo to restore
|
||||||
restore
|
|
||||||
</text>
|
</text>
|
||||||
<Show when={revert()!.diffFiles?.length}>
|
<Show when={revert()!.diffFiles?.length}>
|
||||||
<box marginTop={1}>
|
<box marginTop={1}>
|
||||||
|
|||||||
@@ -220,11 +220,7 @@ export function QuestionPrompt(props: { request: QuestionRequest }) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
...(confirm()
|
...(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) => ({
|
...Array.from({ length: max }, (_, index) => ({
|
||||||
key: String(index + 1),
|
key: String(index + 1),
|
||||||
|
|||||||
@@ -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 === "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.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.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.autocomplete.find((binding) => binding.cmd === "prompt.autocomplete.next")?.key).toBe(
|
||||||
expect(config.keymap.sections.dialog_actions.find((binding) => binding.cmd === "dialog.action.toggle")?.key).toBe("ctrl+t")
|
"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.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.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([
|
expect(config.keymap.pick("plugins", ["plugin.dialog.install"]).map((binding) => binding.cmd)).toEqual([
|
||||||
"plugin.dialog.install",
|
"plugin.dialog.install",
|
||||||
])
|
])
|
||||||
expect(
|
expect((config.keymap.pick("plugins", ["plugin.dialog.install"])[0] as { group?: unknown } | undefined)?.group).toBe(
|
||||||
(config.keymap.pick("plugins", ["plugin.dialog.install"])[0] as { group?: unknown } | undefined)?.group,
|
"Plugins",
|
||||||
).toBe("Plugins")
|
)
|
||||||
expect(config.keymap.omit("plugins", ["plugin.dialog.install"]).map((binding) => binding.cmd)).toEqual([])
|
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.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.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.autocomplete.find((binding) => binding.cmd === "prompt.autocomplete.next")?.key).toBe(
|
||||||
expect(config.keymap.sections.dialog_actions.find((binding) => binding.cmd === "dialog.action.toggle")?.key).toBe("ctrl+t")
|
"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.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.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.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([
|
expect(config.keymap.pick("plugins", ["plugin.dialog.install"]).map((binding) => binding.cmd)).toEqual([
|
||||||
"plugin.dialog.install",
|
"plugin.dialog.install",
|
||||||
])
|
])
|
||||||
expect(
|
expect((config.keymap.omit("plugins", ["plugin.dialog.install"])[0] as { group?: unknown } | undefined)?.group).toBe(
|
||||||
(config.keymap.omit("plugins", ["plugin.dialog.install"])[0] as { group?: unknown } | undefined)?.group,
|
"Plugins",
|
||||||
).toBe("Plugins")
|
)
|
||||||
expect(config.keymap.omit("plugins", ["plugin.dialog.install"]).map((binding) => binding.cmd)).toEqual([
|
expect(config.keymap.omit("plugins", ["plugin.dialog.install"]).map((binding) => binding.cmd)).toEqual([
|
||||||
"plugins.list",
|
"plugins.list",
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -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.
|
`keymap.sections` is grouped by semantic area. Each section contains command names and the key sequence that triggers them.
|
||||||
|
|
||||||
| Field | Description |
|
| Field | Description |
|
||||||
| ----- | ----------- |
|
| ---------------- | --------------------------------------------------------------------------------------------------- |
|
||||||
| `leader` | The key used by `<leader>` sequences. Defaults to `ctrl+x`. |
|
| `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`. |
|
| `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).
|
- `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.
|
- `terminal.suspend` is disabled because native Windows terminals do not support POSIX suspend.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user