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(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() + + 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() @@ -313,22 +357,43 @@ export const SettingsKeybinds: Component = () => { "linear-gradient(to bottom, var(--surface-raised-stronger-non-alpha) calc(100% - 24px), transparent)", }} > -
-

{language.t("settings.shortcuts.title")}

- +
+
+

{language.t("settings.shortcuts.title")}

+ +
+ +
+ + + + setFilter("")} /> + +
{(group) => ( - 0}> + 0}>

{language.t(groupKey[group])}

- + {(id) => (
{title(id)} @@ -357,6 +422,17 @@ export const SettingsKeybinds: Component = () => { )} + + +
+ + {language.t("settings.shortcuts.search.empty")} + + + "{filter()}" + +
+
) 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": "会话",