@@ -10,12 +10,13 @@ import {
1010 useKeymap ,
1111 useKeymapSelector ,
1212} from "@opentui/keymap/solid"
13- import type { Accessor } from "solid-js"
13+ import { createMemo , type Accessor } from "solid-js"
1414import type { TuiConfig } from "./config/tui"
1515import { useTuiConfig } from "./context/tui-config"
1616
1717export const LEADER_TOKEN = "leader"
1818export const OPENCODE_BASE_MODE = "base"
19+ export const COMMAND_PALETTE_COMMAND = "command.palette.show"
1920
2021const OPENCODE_MODE_KEY = "opencode.mode"
2122
@@ -26,9 +27,20 @@ export { useBindings, useKeymapSelector }
2627
2728export type OpenTuiKeymap = ReturnType < typeof useKeymap >
2829type OpencodeModeStack = ReturnType < typeof createOpencodeModeStack >
30+ type CommandSlashEntry = {
31+ display : string
32+ description ?: string
33+ aliases ?: string [ ]
34+ onSelect : ( ) => void
35+ }
36+ type CommandEntry = ReturnType < OpenTuiKeymap [ "getCommandEntries" ] > [ number ]
2937
3038const modeStacks = new WeakMap < OpenTuiKeymap , OpencodeModeStack > ( )
3139
40+ function isVisiblePaletteCommand ( entry : CommandEntry ) {
41+ return entry . command . hidden !== true && entry . command . name !== COMMAND_PALETTE_COMMAND
42+ }
43+
3244export function createOpencodeModeStack ( keymap : OpenTuiKeymap ) {
3345 keymap . setData ( OPENCODE_MODE_KEY , OPENCODE_BASE_MODE )
3446
@@ -145,3 +157,36 @@ export function useCommandShortcut(command: string): Accessor<string> {
145157export function useLeaderActive ( ) : Accessor < boolean > {
146158 return useKeymapSelector ( ( keymap : OpenTuiKeymap ) => keymap . getPendingSequence ( ) [ 0 ] ?. tokenName === LEADER_TOKEN )
147159}
160+
161+ export function useCommandSlashes ( ) : Accessor < readonly CommandSlashEntry [ ] > {
162+ const keymap = useOpencodeKeymap ( )
163+ const entries = useKeymapSelector ( ( keymap : OpenTuiKeymap ) =>
164+ keymap
165+ . getCommandEntries ( {
166+ visibility : "reachable" ,
167+ namespace : "palette" ,
168+ } )
169+ . filter ( isVisiblePaletteCommand ) ,
170+ )
171+
172+ return createMemo < CommandSlashEntry [ ] > ( ( ) =>
173+ entries ( ) . flatMap ( ( entry ) => {
174+ const slashName = entry . command . slashName
175+ if ( typeof slashName !== "string" || ! slashName ) return [ ]
176+ const slashAliases = entry . command . slashAliases
177+ return {
178+ display : `/${ slashName } ` ,
179+ description :
180+ typeof entry . command . desc === "string"
181+ ? entry . command . desc
182+ : typeof entry . command . title === "string"
183+ ? entry . command . title
184+ : undefined ,
185+ aliases : Array . isArray ( slashAliases )
186+ ? slashAliases . filter ( ( alias ) : alias is string => typeof alias === "string" ) . map ( ( alias ) => `/${ alias } ` )
187+ : undefined ,
188+ onSelect : ( ) => keymap . dispatchCommand ( entry . command . name ) ,
189+ }
190+ } ) ,
191+ )
192+ }
0 commit comments