Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for finding commands via additional keywords #8

Open
rouilj opened this issue Jan 27, 2023 · 2 comments
Open

Support for finding commands via additional keywords #8

rouilj opened this issue Jan 27, 2023 · 2 comments

Comments

@rouilj
Copy link
Contributor

rouilj commented Jan 27, 2023

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:

  commands: [
    {
      name: "Contact author",
      shortcut: "ctrl+E",
      handler: () => alert("Send Message"),
      aliases: [ "email", "reply", "send", "to author"],
    },

I suppose I could create child commands:

  function SendEmail () { ... }
  commands: [
    {
      name: "Contact author",
      shortcut: "ctrl+E",
      handler: () => SendEmail(),
      children: [
        {
            name: "Email author",
            shortcut: "Hmm, why no shortcut?"
            handler: SendEmail(),
        },
        {
            name: "Reply to author",
            handler: SendEmail(),
        },
        {
            name: "Send message to author",
            handler: SendEmail(),
        },
       ...,
    },

but that seems suboptimal for a few reasons:

  1. More code is required to implement.
  2. 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.
    • Ideally your language example should show "Change Language > German" displayed as selection when you type "Ger" in the search box from the top level.
  3. It's not obvious that all these synonyms use the same command and shortcut since they are displayed as different menu items.
  4. It doesn't guide the user to understand the canonical term (and the ability to use a shortcut) for the command.

Thoughts?

@benwinding
Copy link
Owner

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:

  • Finding the "keyboard shortcuts" becomes annoying, since they're scattered in the tree, you have to know the parents to discover them
  • Accidentally pressing them can lead to confusion, if you press ctrl + space + j and it takes you to a nested command, it's confusing
  1. 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.

  1. It's not obvious that all these synonyms use the same command and shortcut since they are displayed as different menu items.
  2. 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:

  • 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

Sorry for the rant 😅

@rouilj
Copy link
Contributor Author

rouilj commented Feb 6, 2023

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 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:

  • 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.

Google chrome menu showing hotkeys at the top level nd on a submenu

  • 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.

  1. 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 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.

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 1 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.

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.

  1. It's not obvious that all these synonyms use the same
    command and shortcut since they are displayed as different menu items.
  2. 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.

Footnotes

  1. matches at the start of a command string rank higher.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants