summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/context/command.tsx
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-01-07 06:54:48 -0600
committerAdam <[email protected]>2026-01-20 07:33:44 -0600
commitdf094a10ff1f1a95f66abc6bdccfa69080480afa (patch)
treeff48a40af84df86e8f675c12f55e930df89f947e /packages/app/src/context/command.tsx
parentde3641e8ebfd6d6d0262289136e970b1ddea54b2 (diff)
downloadopencode-df094a10ff1f1a95f66abc6bdccfa69080480afa.tar.gz
opencode-df094a10ff1f1a95f66abc6bdccfa69080480afa.zip
wip(app): settings
Diffstat (limited to 'packages/app/src/context/command.tsx')
-rw-r--r--packages/app/src/context/command.tsx55
1 files changed, 46 insertions, 9 deletions
diff --git a/packages/app/src/context/command.tsx b/packages/app/src/context/command.tsx
index d8dc13e23..7986e7509 100644
--- a/packages/app/src/context/command.tsx
+++ b/packages/app/src/context/command.tsx
@@ -1,9 +1,26 @@
import { createMemo, createSignal, onCleanup, onMount, type Accessor } from "solid-js"
import { createSimpleContext } from "@opencode-ai/ui/context"
import { useDialog } from "@opencode-ai/ui/context/dialog"
+import { useSettings } from "@/context/settings"
const IS_MAC = typeof navigator === "object" && /(Mac|iPod|iPhone|iPad)/.test(navigator.platform)
+const PALETTE_ID = "command.palette"
+const DEFAULT_PALETTE_KEYBIND = "mod+shift+p"
+const SUGGESTED_PREFIX = "suggested."
+
+function actionId(id: string) {
+ if (!id.startsWith(SUGGESTED_PREFIX)) return id
+ return id.slice(SUGGESTED_PREFIX.length)
+}
+
+function normalizeKey(key: string) {
+ if (key === ",") return "comma"
+ if (key === "+") return "plus"
+ if (key === " ") return "space"
+ return key.toLowerCase()
+}
+
export type KeybindConfig = string
export interface Keybind {
@@ -73,7 +90,7 @@ export function parseKeybind(config: string): Keybind[] {
}
export function matchKeybind(keybinds: Keybind[], event: KeyboardEvent): boolean {
- const eventKey = event.key.toLowerCase()
+ const eventKey = normalizeKey(event.key)
for (const kb of keybinds) {
const keyMatch = kb.key === eventKey
@@ -105,15 +122,18 @@ export function formatKeybind(config: string): string {
if (kb.meta) parts.push(IS_MAC ? "⌘" : "Meta")
if (kb.key) {
- const arrows: Record<string, string> = {
+ const keys: Record<string, string> = {
arrowup: "↑",
arrowdown: "↓",
arrowleft: "←",
arrowright: "→",
+ comma: ",",
+ plus: "+",
+ space: "Space",
}
+ const key = kb.key.toLowerCase()
const displayKey =
- arrows[kb.key.toLowerCase()] ??
- (kb.key.length === 1 ? kb.key.toUpperCase() : kb.key.charAt(0).toUpperCase() + kb.key.slice(1))
+ keys[key] ?? (key.length === 1 ? key.toUpperCase() : key.charAt(0).toUpperCase() + key.slice(1))
parts.push(displayKey)
}
@@ -124,9 +144,17 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex
name: "Command",
init: () => {
const dialog = useDialog()
+ const settings = useSettings()
const [registrations, setRegistrations] = createSignal<Accessor<CommandOption[]>[]>([])
const [suspendCount, setSuspendCount] = createSignal(0)
+ const bind = (id: string, def: KeybindConfig | undefined) => {
+ const custom = settings.keybinds.get(actionId(id))
+ const config = custom ?? def
+ if (!config || config === "none") return
+ return config
+ }
+
const options = createMemo(() => {
const seen = new Set<string>()
const all: CommandOption[] = []
@@ -139,15 +167,20 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex
}
}
- const suggested = all.filter((x) => x.suggested && !x.disabled)
+ const resolved = all.map((opt) => ({
+ ...opt,
+ keybind: bind(opt.id, opt.keybind),
+ }))
+
+ const suggested = resolved.filter((x) => x.suggested && !x.disabled)
return [
...suggested.map((x) => ({
...x,
- id: "suggested." + x.id,
+ id: SUGGESTED_PREFIX + x.id,
category: "Suggested",
})),
- ...all,
+ ...resolved,
]
})
@@ -169,7 +202,7 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex
const handleKeyDown = (event: KeyboardEvent) => {
if (suspended() || dialog.active) return
- const paletteKeybinds = parseKeybind("mod+shift+p")
+ const paletteKeybinds = parseKeybind(settings.keybinds.get(PALETTE_ID) ?? DEFAULT_PALETTE_KEYBIND)
if (matchKeybind(paletteKeybinds, event)) {
event.preventDefault()
showPalette()
@@ -209,7 +242,11 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex
run(id, source)
},
keybind(id: string) {
- const option = options().find((x) => x.id === id || x.id === "suggested." + id)
+ if (id === PALETTE_ID) {
+ return formatKeybind(settings.keybinds.get(PALETTE_ID) ?? DEFAULT_PALETTE_KEYBIND)
+ }
+
+ const option = options().find((x) => x.id === id || x.id === SUGGESTED_PREFIX + id)
if (!option?.keybind) return ""
return formatKeybind(option.keybind)
},