summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src
diff options
context:
space:
mode:
authorRahul A Mistry <[email protected]>2026-01-21 22:05:15 +0530
committerGitHub <[email protected]>2026-01-21 10:35:15 -0600
commitb8a0e420f8e8c3abb8ceceecb3e511236e2e9735 (patch)
tree47e1a374574b326cc959ffb3d75528b5ef21f25f /packages/app/src
parentbfbcbc88632869f1a6b86b05a3fff0c7a46e5863 (diff)
downloadopencode-b8a0e420f8e8c3abb8ceceecb3e511236e2e9735.tar.gz
opencode-b8a0e420f8e8c3abb8ceceecb3e511236e2e9735.zip
feat(app): search on settings shortcuts (#9850)
Diffstat (limited to 'packages/app/src')
-rw-r--r--packages/app/src/components/settings-keybinds.tsx90
-rw-r--r--packages/app/src/i18n/da.ts2
-rw-r--r--packages/app/src/i18n/de.ts2
-rw-r--r--packages/app/src/i18n/en.ts2
-rw-r--r--packages/app/src/i18n/es.ts2
-rw-r--r--packages/app/src/i18n/fr.ts2
-rw-r--r--packages/app/src/i18n/ja.ts2
-rw-r--r--packages/app/src/i18n/ko.ts2
-rw-r--r--packages/app/src/i18n/zh.ts2
9 files changed, 99 insertions, 7 deletions
diff --git a/packages/app/src/components/settings-keybinds.tsx b/packages/app/src/components/settings-keybinds.tsx
index 13a0042ff..3f1f34e5f 100644
--- a/packages/app/src/components/settings-keybinds.tsx
+++ b/packages/app/src/components/settings-keybinds.tsx
@@ -1,6 +1,10 @@
import { Component, For, Show, createMemo, createSignal, onCleanup, onMount } from "solid-js"
import { Button } from "@opencode-ai/ui/button"
+import { Icon } from "@opencode-ai/ui/icon"
+import { IconButton } from "@opencode-ai/ui/icon-button"
+import { TextField } from "@opencode-ai/ui/text-field"
import { showToast } from "@opencode-ai/ui/toast"
+import fuzzysort from "fuzzysort"
import { formatKeybind, parseKeybind, useCommand } from "@/context/command"
import { useLanguage } from "@/context/language"
import { useSettings } from "@/context/settings"
@@ -108,6 +112,7 @@ export const SettingsKeybinds: Component = () => {
const settings = useSettings()
const [active, setActive] = createSignal<string | null>(null)
+ const [filter, setFilter] = createSignal("")
const stop = () => {
if (!active()) return
@@ -197,6 +202,45 @@ export const SettingsKeybinds: Component = () => {
return out
})
+ const filtered = createMemo(() => {
+ const query = filter().toLowerCase().trim()
+ if (!query) return grouped()
+
+ const map = list()
+ const out = new Map<KeybindGroup, string[]>()
+
+ for (const group of GROUPS) out.set(group, [])
+
+ const items = Array.from(map.entries()).map(([id, meta]) => ({
+ id,
+ title: meta.title,
+ group: meta.group,
+ keybind: command.keybind(id) || "",
+ }))
+
+ const results = fuzzysort.go(query, items, {
+ keys: ["title", "keybind"],
+ threshold: -10000,
+ })
+
+ for (const result of results) {
+ const item = result.obj
+ const ids = out.get(item.group)
+ if (!ids) continue
+ ids.push(item.id)
+ }
+
+ return out
+ })
+
+ const hasResults = createMemo(() => {
+ for (const group of GROUPS) {
+ const ids = filtered().get(group) ?? []
+ if (ids.length > 0) return true
+ }
+ return false
+ })
+
const used = createMemo(() => {
const map = new Map<string, { id: string; title: string }[]>()
@@ -313,22 +357,43 @@ export const SettingsKeybinds: Component = () => {
"linear-gradient(to bottom, var(--surface-raised-stronger-non-alpha) calc(100% - 24px), transparent)",
}}
>
- <div class="flex items-center justify-between gap-4 pt-6 pb-8 max-w-[720px]">
- <h2 class="text-16-medium text-text-strong">{language.t("settings.shortcuts.title")}</h2>
- <Button size="small" variant="secondary" onClick={resetAll} disabled={!hasOverrides()}>
- {language.t("settings.shortcuts.reset.button")}
- </Button>
+ <div class="flex flex-col gap-4 pt-6 pb-6 max-w-[720px]">
+ <div class="flex items-center justify-between gap-4">
+ <h2 class="text-16-medium text-text-strong">{language.t("settings.shortcuts.title")}</h2>
+ <Button size="small" variant="secondary" onClick={resetAll} disabled={!hasOverrides()}>
+ {language.t("settings.shortcuts.reset.button")}
+ </Button>
+ </div>
+
+ <div class="flex items-center gap-2 px-3 py-2 rounded-lg bg-surface-base">
+ <Icon name="magnifying-glass" class="text-icon-weak-base flex-shrink-0" />
+ <TextField
+ variant="ghost"
+ type="text"
+ value={filter()}
+ onChange={setFilter}
+ placeholder={language.t("settings.shortcuts.search.placeholder")}
+ spellcheck={false}
+ autocorrect="off"
+ autocomplete="off"
+ autocapitalize="off"
+ class="flex-1"
+ />
+ <Show when={filter()}>
+ <IconButton icon="circle-x" variant="ghost" onClick={() => setFilter("")} />
+ </Show>
+ </div>
</div>
</div>
<div class="flex flex-col gap-8 max-w-[720px]">
<For each={GROUPS}>
{(group) => (
- <Show when={(grouped().get(group) ?? []).length > 0}>
+ <Show when={(filtered().get(group) ?? []).length > 0}>
<div class="flex flex-col gap-1">
<h3 class="text-14-medium text-text-strong pb-2">{language.t(groupKey[group])}</h3>
<div class="bg-surface-raised-base px-4 rounded-lg">
- <For each={grouped().get(group) ?? []}>
+ <For each={filtered().get(group) ?? []}>
{(id) => (
<div class="flex items-center justify-between gap-4 py-3 border-b border-border-weak-base last:border-none">
<span class="text-14-regular text-text-strong">{title(id)}</span>
@@ -357,6 +422,17 @@ export const SettingsKeybinds: Component = () => {
</Show>
)}
</For>
+
+ <Show when={filter() && !hasResults()}>
+ <div class="flex flex-col items-center justify-center py-12 text-center">
+ <span class="text-14-regular text-text-weak">
+ {language.t("settings.shortcuts.search.empty")}
+ </span>
+ <Show when={filter()}>
+ <span class="text-14-regular text-text-strong mt-1">"{filter()}"</span>
+ </Show>
+ </div>
+ </Show>
</div>
</div>
)
diff --git a/packages/app/src/i18n/da.ts b/packages/app/src/i18n/da.ts
index 9f87cc987..7d381a820 100644
--- a/packages/app/src/i18n/da.ts
+++ b/packages/app/src/i18n/da.ts
@@ -466,6 +466,8 @@ export const dict = {
"settings.shortcuts.conflict.description": "{{keybind}} er allerede tildelt til {{titles}}.",
"settings.shortcuts.unassigned": "Ikke tildelt",
"settings.shortcuts.pressKeys": "Tryk på taster",
+ "settings.shortcuts.search.placeholder": "Søg genveje",
+ "settings.shortcuts.search.empty": "Ingen genveje fundet",
"settings.shortcuts.group.general": "Generelt",
"settings.shortcuts.group.session": "Session",
diff --git a/packages/app/src/i18n/de.ts b/packages/app/src/i18n/de.ts
index c0100f95e..495308a6f 100644
--- a/packages/app/src/i18n/de.ts
+++ b/packages/app/src/i18n/de.ts
@@ -475,6 +475,8 @@ export const dict = {
"settings.shortcuts.conflict.description": "{{keybind}} ist bereits {{titles}} zugewiesen.",
"settings.shortcuts.unassigned": "Nicht zugewiesen",
"settings.shortcuts.pressKeys": "Tasten drücken",
+ "settings.shortcuts.search.placeholder": "Tastenkürzel suchen",
+ "settings.shortcuts.search.empty": "Keine Tastenkürzel gefunden",
"settings.shortcuts.group.general": "Allgemein",
"settings.shortcuts.group.session": "Sitzung",
diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts
index 7e7c6f790..8e4c9aa50 100644
--- a/packages/app/src/i18n/en.ts
+++ b/packages/app/src/i18n/en.ts
@@ -465,6 +465,8 @@ export const dict = {
"settings.shortcuts.conflict.description": "{{keybind}} is already assigned to {{titles}}.",
"settings.shortcuts.unassigned": "Unassigned",
"settings.shortcuts.pressKeys": "Press keys",
+ "settings.shortcuts.search.placeholder": "Search shortcuts",
+ "settings.shortcuts.search.empty": "No shortcuts found",
"settings.shortcuts.group.general": "General",
"settings.shortcuts.group.session": "Session",
diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts
index 224c8eedf..bae4ad480 100644
--- a/packages/app/src/i18n/es.ts
+++ b/packages/app/src/i18n/es.ts
@@ -469,6 +469,8 @@ export const dict = {
"settings.shortcuts.conflict.description": "{{keybind}} ya está asignado a {{titles}}.",
"settings.shortcuts.unassigned": "Sin asignar",
"settings.shortcuts.pressKeys": "Presiona teclas",
+ "settings.shortcuts.search.placeholder": "Buscar atajos",
+ "settings.shortcuts.search.empty": "No se encontraron atajos",
"settings.shortcuts.group.general": "General",
"settings.shortcuts.group.session": "Sesión",
diff --git a/packages/app/src/i18n/fr.ts b/packages/app/src/i18n/fr.ts
index e76e13938..c00142100 100644
--- a/packages/app/src/i18n/fr.ts
+++ b/packages/app/src/i18n/fr.ts
@@ -475,6 +475,8 @@ export const dict = {
"settings.shortcuts.conflict.description": "{{keybind}} est déjà assigné à {{titles}}.",
"settings.shortcuts.unassigned": "Non assigné",
"settings.shortcuts.pressKeys": "Appuyez sur les touches",
+ "settings.shortcuts.search.placeholder": "Rechercher des raccourcis",
+ "settings.shortcuts.search.empty": "Aucun raccourci trouvé",
"settings.shortcuts.group.general": "Général",
"settings.shortcuts.group.session": "Session",
diff --git a/packages/app/src/i18n/ja.ts b/packages/app/src/i18n/ja.ts
index 8be5f87d1..c8448811a 100644
--- a/packages/app/src/i18n/ja.ts
+++ b/packages/app/src/i18n/ja.ts
@@ -464,6 +464,8 @@ export const dict = {
"settings.shortcuts.conflict.description": "{{keybind}} は既に {{titles}} に割り当てられています。",
"settings.shortcuts.unassigned": "未割り当て",
"settings.shortcuts.pressKeys": "キーを押してください",
+ "settings.shortcuts.search.placeholder": "ショートカットを検索",
+ "settings.shortcuts.search.empty": "ショートカットが見つかりません",
"settings.shortcuts.group.general": "一般",
"settings.shortcuts.group.session": "セッション",
diff --git a/packages/app/src/i18n/ko.ts b/packages/app/src/i18n/ko.ts
index b612a7873..dbd02270c 100644
--- a/packages/app/src/i18n/ko.ts
+++ b/packages/app/src/i18n/ko.ts
@@ -465,6 +465,8 @@ export const dict = {
"settings.shortcuts.conflict.description": "{{keybind}}은(는) 이미 {{titles}}에 할당되어 있습니다.",
"settings.shortcuts.unassigned": "할당되지 않음",
"settings.shortcuts.pressKeys": "키 누르기",
+ "settings.shortcuts.search.placeholder": "단축키 검색",
+ "settings.shortcuts.search.empty": "단축키를 찾을 수 없습니다",
"settings.shortcuts.group.general": "일반",
"settings.shortcuts.group.session": "세션",
diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts
index f020b10b8..ac976b627 100644
--- a/packages/app/src/i18n/zh.ts
+++ b/packages/app/src/i18n/zh.ts
@@ -459,6 +459,8 @@ export const dict = {
"settings.shortcuts.conflict.description": "{{keybind}} 已分配给 {{titles}}。",
"settings.shortcuts.unassigned": "未设置",
"settings.shortcuts.pressKeys": "按下按键",
+ "settings.shortcuts.search.placeholder": "搜索快捷键",
+ "settings.shortcuts.search.empty": "未找到快捷键",
"settings.shortcuts.group.general": "通用",
"settings.shortcuts.group.session": "会话",