1- import { createContext , createMemo , useContext , type Accessor , type ParentProps } from "solid-js"
1+ import { createMemo , type Accessor , type ParentProps } from "solid-js"
22import { DialogSelect , type DialogSelectRef } from "@tui/ui/dialog-select"
33import { useDialog , type DialogContext } from "@tui/ui/dialog"
44import {
55 formatKeyBindings ,
66 type OpenTuiKeymap ,
7+ useBindings ,
78 useKeymapSelector ,
89 useOpencodeKeymap ,
910} from "../keymap"
@@ -16,14 +17,7 @@ type SlashEntry = {
1617 onSelect : ( ) => void
1718}
1819
19- type CommandPaletteContext = {
20- run ( command : string ) : void
21- show ( ) : void
22- slashes : Accessor < readonly SlashEntry [ ] >
23- }
24-
2520const COMMAND_PALETTE_DIALOG = "command.palette.show"
26- const ctx = createContext < CommandPaletteContext > ( )
2721type PaletteCommandEntry = ReturnType < OpenTuiKeymap [ "getCommandEntries" ] > [ number ]
2822
2923function isVisiblePaletteCommand ( entry : PaletteCommandEntry ) {
@@ -39,60 +33,25 @@ function isSuggestedPaletteCommand(entry: PaletteCommandEntry) {
3933
4034export function CommandPaletteProvider ( props : ParentProps ) {
4135 const dialog = useDialog ( )
42- const keymap = useOpencodeKeymap ( )
43- const entries = useKeymapSelector ( ( keymap : OpenTuiKeymap ) =>
44- keymap
45- . getCommandEntries ( {
46- visibility : "reachable" ,
47- namespace : "palette" ,
48- } )
49- . filter ( isVisiblePaletteCommand ) ,
50- )
51-
52- const run = ( command : string ) => {
53- keymap . dispatchCommand ( command )
54- }
55-
56- const slashes = createMemo < SlashEntry [ ] > ( ( ) =>
57- entries ( ) . flatMap ( ( entry ) => {
58- const slashName = entry . command . slashName
59- if ( typeof slashName !== "string" || ! slashName ) return [ ]
60- const slashAliases = entry . command . slashAliases
61- return {
62- display : `/${ slashName } ` ,
63- description :
64- typeof entry . command . desc === "string"
65- ? entry . command . desc
66- : typeof entry . command . title === "string"
67- ? entry . command . title
68- : undefined ,
69- aliases : Array . isArray ( slashAliases )
70- ? slashAliases . filter ( ( alias ) : alias is string => typeof alias === "string" ) . map ( ( alias ) => `/${ alias } ` )
71- : undefined ,
72- onSelect : ( ) => run ( entry . command . name ) ,
73- }
74- } ) ,
75- )
76-
77- const value : CommandPaletteContext = {
78- run,
79- show ( ) {
80- dialog . replace ( ( ) => < CommandPaletteDialog run = { run } /> )
81- } ,
82- slashes,
83- }
84-
85- return < ctx . Provider value = { value } > { props . children } </ ctx . Provider >
86- }
36+ useBindings ( ( ) => ( {
37+ commands : [
38+ {
39+ name : COMMAND_PALETTE_DIALOG ,
40+ title : "Show command palette" ,
41+ hidden : true ,
42+ run ( ) {
43+ dialog . replace ( ( ) => < CommandPaletteDialog /> )
44+ } ,
45+ } ,
46+ ] ,
47+ } ) )
8748
88- export function useCommandPalette ( ) {
89- const value = useContext ( ctx )
90- if ( ! value ) throw new Error ( "CommandPalette context must be used within a CommandPaletteProvider" )
91- return value
49+ return < > { props . children } </ >
9250}
9351
94- function CommandPaletteDialog ( props : { run ( command : string ) : void } ) {
52+ function CommandPaletteDialog ( ) {
9553 const config = useTuiConfig ( )
54+ const keymap = useOpencodeKeymap ( )
9655 const entries = useKeymapSelector ( ( keymap : OpenTuiKeymap ) => {
9756 const query = {
9857 namespace : "palette" ,
@@ -123,7 +82,7 @@ function CommandPaletteDialog(props: { run(command: string): void }) {
12382 suggested : isSuggestedPaletteCommand ( entry ) ,
12483 onSelect : ( dialog : DialogContext ) => {
12584 dialog . clear ( )
126- props . run ( entry . command . name )
85+ keymap . dispatchCommand ( entry . command . name )
12786 } ,
12887 } ) ) ,
12988 )
@@ -147,5 +106,34 @@ function CommandPaletteDialog(props: { run(command: string): void }) {
147106}
148107
149108export function useCommandSlashes ( ) : Accessor < readonly SlashEntry [ ] > {
150- return useCommandPalette ( ) . slashes
109+ const keymap = useOpencodeKeymap ( )
110+ const entries = useKeymapSelector ( ( keymap : OpenTuiKeymap ) =>
111+ keymap
112+ . getCommandEntries ( {
113+ visibility : "reachable" ,
114+ namespace : "palette" ,
115+ } )
116+ . filter ( isVisiblePaletteCommand ) ,
117+ )
118+
119+ return createMemo < SlashEntry [ ] > ( ( ) =>
120+ entries ( ) . flatMap ( ( entry ) => {
121+ const slashName = entry . command . slashName
122+ if ( typeof slashName !== "string" || ! slashName ) return [ ]
123+ const slashAliases = entry . command . slashAliases
124+ return {
125+ display : `/${ slashName } ` ,
126+ description :
127+ typeof entry . command . desc === "string"
128+ ? entry . command . desc
129+ : typeof entry . command . title === "string"
130+ ? entry . command . title
131+ : undefined ,
132+ aliases : Array . isArray ( slashAliases )
133+ ? slashAliases . filter ( ( alias ) : alias is string => typeof alias === "string" ) . map ( ( alias ) => `/${ alias } ` )
134+ : undefined ,
135+ onSelect : ( ) => keymap . dispatchCommand ( entry . command . name ) ,
136+ }
137+ } ) ,
138+ )
151139}
0 commit comments