Skip to content

SpaceDance: leader menus

Tom Short edited this page Nov 7, 2021 · 6 revisions

This section covers options to create your own leader menus, ala Spacemacs.

which-key

which-key is a menu system used by VSpaceCode. This is an easy way to add a leader menu system to Dance. Just add this extension, and assign whichkey.show to a launching key. It provides a basic tree of menus. You can customize the menu as shown here.

The format for which-key menu descriptions are a little more verbose than Dance menu descriptions. Using which-key has some advantages:

  • Menus can include an icon.
  • Menus can be conditional based on the current mode of the buffer, and most importantly...
  • Other people provide the testing and updates to the menu tree.

VSpaceCode menu tree

VSpaceCode provides a deeper set of menus. You can include the entire tree by copying this set of configuration lines (6000+ lines) into the following snippet in settings.json.

   "whichkey.bindings": [
       // paste here...
   ],

This gives the entire VSpaceCode menu tree described here. It works pretty nice, and it has icons. Some of the menu options require extensions ("kahole.magit", "jacobdufault.fuzzy-search", and "bodil.file-browser"). Some of the commands require VSCodeVim, and those would need to be redefined with Dance equivalents.

It's also possible to customize the styling of the which-key menus as shown here.

Assigning the leader key

Which key do you assign the leader menu to? space is the obvious choice, but the space key is a useful Kakoune / Dance key. That needs to be remapped if you want to use the space key as the main leader. Here is an example using the ' key:

    {
        "key": "'",
        "command": "dance.selections.clear.secondary",
        "when": "!inputFocus || editorTextFocus && dance.mode == 'normal'"
    },
    {
        "key": "Alt+'",
        "command": "dance.selections.clear.main",
        "when": "!inputFocus || editorTextFocus && dance.mode == 'normal'"
    },
    {
        "key": "space",
        "command": "whichkey.show",
        "when": "editorTextFocus && dance.mode == 'normal'",
    },
    {
        "key": ",",
        "command": "dance.run",
        "args": {
            "commands": [
                "whichkey.show",
                {"command": "whichkey.triggerKey", "args": "m"},
            ]
        },
        "when": "editorTextFocus && dance.mode == 'normal'",
    },
    {
        "key": "space",
        "command": "whichkey.show",
        "when": "sideBarFocus && !inputFocus && !whichkeyActive"
    },
    {
        "key": "f1",
        "command": "whichkey.show",
    },

This example also includes a global key for launching the main menu (F1). It also binds the , key to the space-m menu, the mode-specific menu.

If you want F1 to work in terminals, you also need the following in settings.json:

    "terminal.integrated.commandsToSkipShell": ["whichkey.show"],

The : key is another good option for assigning dance.selections.clear.secondary instead of space. In the VSpaceCode menu, the replacement for : is to hit the spacebar twice (runs workbench.action.showCommands).

      {
        "key": "Shift+;",
        "command": "dance.selections.clear.secondary",
        "when": "!inputFocus || editorTextFocus && dance.mode == 'normal'"
      },

Yet another option is to assign dance.selections.clear.secondary to ; and move dance.selections.reduce from ; to :.

      {
        "key": "Shift+;",
        "when": "editorTextFocus && dance.mode == 'normal'",
        "title": "Reduce selections to their cursor",
        "command": "dance.selections.reduce"
      },
      {
        "key": ";",
        "command": "dance.selections.clear.secondary",
        "when": "!inputFocus || editorTextFocus && dance.mode == 'normal'"
      },

Native Dance menus

As described here, there are a couple of ways to define a menu tree with Dance menus.