global keybinds

This commit is contained in:
Sebastian Herrlinger
2026-05-26 23:53:54 +02:00
parent 0448a30821
commit f342d61cef
2 changed files with 74 additions and 4 deletions
+10 -3
View File
@@ -79,10 +79,8 @@ import {
import type { EventSource } from "./context/sdk"
import { DialogVariant } from "./component/dialog-variant"
const appBindingCommands = [
"command.palette.show",
const appGlobalBindingCommands = [
"session.list",
"session.new",
"session.quick_switch.1",
"session.quick_switch.2",
"session.quick_switch.3",
@@ -92,6 +90,11 @@ const appBindingCommands = [
"session.quick_switch.7",
"session.quick_switch.8",
"session.quick_switch.9",
] as const
const appBindingCommands = [
"command.palette.show",
"session.new",
"model.list",
"model.cycle_recent",
"model.cycle_recent_reverse",
@@ -929,6 +932,10 @@ function App(props: { onSnapshot?: () => Promise<string[]> }) {
bindings: tuiConfig.keybinds.gather("app", appBindingCommands),
}))
useBindings(() => ({
bindings: tuiConfig.keybinds.gather("app.global", appGlobalBindingCommands),
}))
useBindings(() => ({
mode: OPENCODE_BASE_MODE,
enabled: () => {
+64 -1
View File
@@ -4,7 +4,12 @@ import { testRender, useRenderer } from "@opentui/solid"
import { expect, test } from "bun:test"
import { onCleanup } from "solid-js"
import { createTuiResolvedConfig } from "../../fixture/tui-runtime"
import { OpencodeKeymapProvider, registerOpencodeKeymap } from "@/cli/cmd/tui/keymap"
import {
getOpencodeModeStack,
OPENCODE_BASE_MODE,
OpencodeKeymapProvider,
registerOpencodeKeymap,
} from "@/cli/cmd/tui/keymap"
test("legacy page key aliases compile as page keys", async () => {
const sequences: Record<string, string[][]> = {}
@@ -52,3 +57,61 @@ test("legacy page key aliases compile as page keys", async () => {
app.renderer.destroy()
}
})
test("mode-less bindings stay active when opencode mode changes", async () => {
const counts: Record<string, Record<string, number>> = {}
function Harness() {
const renderer = useRenderer()
const keymap = createDefaultOpenTuiKeymap(renderer)
const config = createTuiResolvedConfig()
const offKeymap = registerOpencodeKeymap(keymap, renderer, config)
const offGlobal = keymap.registerLayer({
commands: [{ name: "session.list", run() {} }],
bindings: config.keybinds.gather("test.global", ["session.list"]),
})
const offBase = keymap.registerLayer({
mode: OPENCODE_BASE_MODE,
commands: [{ name: "session.new", run() {} }],
bindings: config.keybinds.gather("test.base", ["session.new"]),
})
const activeCounts = () =>
Object.fromEntries(
Array.from(
keymap.getCommandBindings({ visibility: "active", commands: ["session.list", "session.new"] }),
([command, bindings]) => [command, bindings.length],
),
)
counts.base = activeCounts()
const popQuestion = getOpencodeModeStack(keymap).push("question")
counts.question = activeCounts()
popQuestion()
const popAutocomplete = getOpencodeModeStack(keymap).push("autocomplete")
counts.autocomplete = activeCounts()
popAutocomplete()
onCleanup(() => {
offBase()
offGlobal()
offKeymap()
})
return (
<OpencodeKeymapProvider keymap={keymap}>
<box />
</OpencodeKeymapProvider>
)
}
const app = await testRender(() => <Harness />)
try {
expect(counts).toEqual({
base: { "session.list": 1, "session.new": 1 },
question: { "session.list": 1, "session.new": 0 },
autocomplete: { "session.list": 1, "session.new": 0 },
})
} finally {
app.renderer.destroy()
}
})