Open rouilj opened 1 year ago
Thanks for the details, here's some thoughts of mine
I was looking for a command palette to add to my roundup issue tracker tracker template. It looks like command-pal and ninja-keys are the only two implementations that work with vanilla JS.
I had no idea about ninja-keys
, looks like a good implementation π
Fuzzy search works well for typos, but suppose I want a search for email to find the "Contact" command in my palette? Obviously fuzzy search won't handle that. Is there an alias/keyword array property that fuzzy search will look at to select the Contact field?
That was the idea behind the description
field, as you discovered in #9
children: [ { name: "Email author", shortcut: "Hmm, why no shortcut?" handler: SendEmail(), },
Child commands cannot have shortcuts
by design, as shortcuts are global and thus belong in the top level command array. This is inspired by VScode
which in my opinion has one of the most ergonomic and easy to use Command Palettes.
The alternative would be to allow any command in the tree to have a shortcut
which creates several annoying problems for the user:
ctrl + space + j
and it takes you to a nested command, it's confusing
The UI requires navigating into the "Contact Author" command submenu. This requires retyping the search rather than just selecting the primary menu item.
- Also by navigating into the submenu, you loose context. Only the submenu items are shown, there is no breadcrumb. For example: in your advanced language example, you can search for German, and it shows "Change Language". But once you change to the submenu, there is no hint that you are under the "Change Language" submenu. The prompt doesn't change to indicate where you are in the hierarchy.
These are great points, I think 'breadcrumbs' or something to denote where you are is a good idea, especially for the "Change Language" example.
- Ideally your language example should show "Change Language > German" displayed as selection when you type "Ger" in the search box from the top level.
I don't agree that the command should match any child command from the top level. This would mean you get possibly hundreds of results which aren't specific to the current level you're on. Example: if I type Sav
to find the Save
command I could be shown "Change Language > Savant Icelandic" or something, which to me is confusing and unintuitive.
I guess I see the "Command Palette" as a filter, rather than a search. You only filter what's in the list you can scroll.
- It's not obvious that all these synonyms use the same command and shortcut since they are displayed as different menu items.
- It doesn't guide the user to understand the canonical term (and the ability to use a shortcut) for the command.
Not exactly sure what you mean here ^ the command matches according to the description
- which isn't shown to the user - but the "canonical term" is displayed to the user.
In my experience, the best systems have a single top-level command layer which have keyboard shortcuts and all child commands are accessible from that top level. This is important for many reasons:
Sorry for the rant π
Sorry for the rant π
No problem at all. It was less rant and more background perspective. Now you can read my rant 8-).
suppose I want a search for email to find the "Contact" command [...] Is there an alias/keyword array property that fuzzy search will look at to select the Contact field?
That was the idea behind the description field, as you discovered in #9
The problem I see/have had is lack of search result context for the match. I might not be thinking "Contact" in terms of email, but say Contact in terms of paper[1]. This is why people do card sorting exercises to understand a term's context.
[1]: shelf liner or whatever it's called in your neck of the woods.
If I see Contact
without a hint that it should be interpreted as in the context of email I'll be confused. Especially when fuzzy search is added in. You get some wacky matches returned that will have nothing to do with what you are looking for. Search for engl
and get Kongo? Really? I'm not a great typist but I would have to be really bad to want to match Kongo by typing engl 8-). It's the nature of the search but...
Being able to view the description would add context in situations like this.
This is why in #30 the user gets feedback on the "most likely" fuzzy alias match.
To deal with the Kongo result, there could be another parameter, a user/developer defined cutoff so terms like Kongo that score higher (0 perfect match 1, bad match) are filtered from the result set.
Child commands cannot have
shortcuts
by design, as shortcuts are global and thus belong in the top level command array. This is inspired byVScode
which in my opinion has one of the most ergonomic and easy to use Command Palettes.The alternative would be to allow any command in the tree to have a
shortcut
which creates several annoying problems for the user:
- Finding the "keyboard shortcuts" becomes annoying, since they're scattered in the tree, you have to know the parents to discover them
Fair enough. The discovery issue is real. I don't use VScode, you can pry emacs out of my cold dead hands 8-).
Just as a counterpoint, menus have shortcut keys at the lower levels. Granted menus rarely exceed three levels. E.g.
- Accidentally pressing them can lead to confusion, if you press
ctrl + space + j
and it takes you to a nested command, it's confusing
Well it should just execute a nested command. Which actually brings up another point. Why does command-pal display itself when activating a hotkey? Is that another vscode thing? If I use a hotkey for example in chrome the menu system doesn't display, the action just happens.
[warning random aside ahead]
Regarding ctrl + space + j
jumping to a random command. Does it make sense to provide some way to search for command by hotkey? So you could type: ~ctrl+space+j
and find random command
. I know some command palettes can do what I will term faceted search by prepending a character. For example GitHub uses a search starting with #
to search issues, pull requests etc. If the search starts with !
it searches the project namespace.
I doubt this would be useful for hotkey discovery though 8-). [back to main trail]
If the hotkey opens the command-pal nested menu, then displaying the top level command palette and moving to the submenu makes sense.
The UI requires navigating into the "Contact Author" command submenu. This requires retyping the search rather than just selecting the primary menu item.
- Also by navigating into the submenu, you loose context. Only the submenu items are shown, there is no breadcrumb. [...] The prompt doesn't change to indicate where you are in the hierarchy. These are great points, I think 'breadcrumbs' or something to denote where you are is a good idea, especially for the "Change Language" example.
It could add a small breadcrumb in the header above the search box Change Language >
.
- Ideally your language example should show "Change Language > German" displayed as selection when you type "Ger" in the search box from the top level.
I don't agree that the command should match any child command from the top level. This would mean you get possibly hundreds of results which aren't specific to the current level you're on. Example: if I type
Sav
to find theSave
command I could be shown "Change Language > Savant Icelandic" or something, which to me is confusing and unintuitive.I guess I see the "Command Palette" as a filter, rather than a search. You only filter what's in the list you can scroll.
Another way to look at command palette is a searchable omnipotent menu.
Also wouldn't this depend on usage. For example take a top level menu with Save
and a nested Formatting
menu.
If I type: suv
wouldn't it be nice to get:
Save (ctrl+s)
Formatting > Subscript
Formatting > Superscript
I could create top level commands named Formatting > Subscript
or probably better [^2] Subscript < Formatting
etc. But I may want to make discovery of other formatting commands easier by arranging them in a nested menu. To your point about getting hits from outside of your expected realm, typing "form" may not show only formatting commands but fill out form a
and fill out form b
commands. With a nested menu, the user can type format
and see the (probably only) matching menu item and its hotkey. Then choose the nested menu that only has formatting commands.
[^2]: matches at the start of a command string rank higher.
Also regarding the nested menu, how do I go up a level? Ninja-Keys uses backspace when invoked in an empty search box at a child menu level IIRC.
- It's not obvious that all these synonyms use the same command and shortcut since they are displayed as different menu items.
- It doesn't guide the user to understand the canonical term (and the ability to use a shortcut) for the command.
Not exactly sure what you mean here ^ the command matches according to the
description
- which isn't shown to the user - but the "canonical term" is displayed to the user.
Given my explanation of search result context above, does 4 make more sense? Not displaying the description leaves the user wondering why the result is shown.
In any case using a nested list is not right for my use case.
In my experience, the best systems have a single top-level command layer which have keyboard shortcuts and all child commands are accessible from that top level. This is important for many reasons:
User's Perspective
- Shows the user all possible "keyboard shortcuts" in the first level
- Makes the API simpler to use
Developer's Perspective
- Easier to track all possible "keyboard shortcuts"
- Encourages only important shortcuts, not ones hidden in nested levels
- Encourages a simpler experience
All laudable goals.
Hello:
I was looking for a command palette to add to my roundup issue tracker tracker template. It looks like command-pal and ninja-keys are the only two implementations that work with vanilla JS.
Fuzzy search works well for typos, but suppose I want a search for email to find the "Contact" command in my palette? Obviously fuzzy search won't handle that. Is there an alias/keyword array property that fuzzy search will look at to select the Contact field? I envision something like:
I suppose I could create child commands:
but that seems suboptimal for a few reasons:
Thoughts?