DataviewJS Snippet Showcase

Last july, @Moonbase59 , created a script to list the current hotkeys, and I got news of this today. I discovered that if multiple keys was defined, it didn’t show the alternate keys provided, so I modified the scripts a little.

Modifications I made to script include:

  • Allowing for showing multiple keys for a given command
  • Simplified the join operations on the modifiers, and allowed for usage of symbols, if one are so inclined
  • Changed the second listing to only show commands without a hotkey, and as a result I also removed the hotkey column for that listing
  • Provided in-code examples of how to sort on either columns by changing which .sort() command is commented or not

With these listing I can now easier find conflicting hotkeys (even if more than two commands use the same key combination), and also easier see commands available for hotkeys.

New variant of Commands vs Hotkeys

### Commands with hotkeys sorted by name
```dataviewjs

function joinModifiers(modifiers, symbols=false) {
	return modifiers.join(' ')
	                .replace('Mod', symbols ? '⌘' : 'CMD')
    	            .replace('Alt', symbols ? '⌥' : 'OPT')
    	            .replace('Ctrl', symbols ? '⌃' : 'CTRL')
    	            .replace('Shift', symbols ? '⇧' : 'SHIFT')
}

function getHotkey(arr, highlight=true) {
    let hi = highlight ? '**' : '';
    let keys = []; // Store all key combinations defined for this command
    let currKey = ""

    // Find the default key setting for the command, if any
    if (arr.hotkeys && arr.hotkeys.length > 0) {
      console.log(arr.hotkeys)
      for (let aKey of arr.hotkeys) {
    	 keys.push(joinModifiers(aKey.modifiers) + ' ' + aKey.key)
      }
    }
      
    // Handle custom hotkey setup, with possible multiple assignments
    let ck = app.hotkeyManager.customKeys[arr.id];
    if (ck) { 
      // Reset keys array, as custom keys override the default key setting
      keys = []
      for (let aKey of ck) {
    	 keys.push(hi + joinModifiers(aKey.modifiers) + ' ' + aKey.key + hi)
      }
    } 
    
	return (keys.length != 0) ? keys.join('<br />') : 'none';
}

let cmds = dv.array(Object.entries(app.commands.commands))
    .where(v => getHotkey(v[1]) != 'none')
    //// Choose your sorting option by changing which line is commented out
    .sort(v => v[1].id, 'asc'); // Sorted by the command name
    // .sort(v => v[1].id, 'asc'); // Sorted by the descriptive name
    //.sort(v => getHotkey(v[1], false), 'asc'); // Sorted by hotkey

dv.paragraph(cmds.length + " hotkeys. " +
    "Both 'default' and <strong>'custom'</strong>.<br><br>");

dv.table(["Command", "Name", "Hotkeys"],
  cmds.map(v => [
    v[1].id,
    v[1].name,
    getHotkey(v[1]),
    ])
  );
```

### Other available commands with no key assigned

```dataviewjs

function getHotkey(arr, highlight=true) {
    let hi = highlight ? '**' : '';
    let keys = []; // Store all key combinations defined for this command
    let currKey = ""

    // Find the default key setting for the command, if any
    if (arr.hotkeys && arr.hotkeys.length > 0) {
      console.log(arr.hotkeys)
      for (let aKey of arr.hotkeys) {
    	 keys.push(aKey.modifiers.join(' ')
    	               .replace('Mod', 'CMD')
    	               .replace('Alt', 'OPT')
    	               .replace('Ctrl', 'CTRL')
    	               .replace('Shift', 'SHIFT')
    	            + ' ' + aKey.key);
      }
    }
      
    // Handle custom hotkey setup, with possible multiple assignments
    let ck = app.hotkeyManager.customKeys[arr.id];
    if (ck) { 
      // Reset keys array, as custom keys override the default key settings
      keys = []
      for (let aKey of ck) {
    	 keys.push(hi + aKey.modifiers.join(' ')
    	                .replace('Mod', 'CMD')
    	                .replace('Alt', 'OPT')
    	                .replace('Ctrl', 'CTRL')
    	                .replace('Shift', 'SHIFT')
    	              + ' ' + aKey.key + hi)
      }
    } 
    
	return (keys.length != 0) ? keys.join('<br />') : 'none';
}

let cmds = dv.array(Object.entries(app.commands.commands))
    .where(v => getHotkey(v[1]) == 'none')
    //// Choose your sorting option by changing which line is commented out
    .sort(v => v[1].id, 'asc'); // Sorted by the command name
    // .sort(v => v[1].id, 'asc'); // Sorted by the descriptive name
    //.sort(v => getHotkey(v[1], false), 'asc'); // Sorted by hotkey

dv.paragraph(cmds.length + " commands. " +
    "Rest of commands which doesn't have any keys assigned to them.<br><br>");

dv.table(["Command", "Name"],
  cmds.map(v => [
    v[1].id,
    v[1].name])
  );
```

In the image below you can see the top part of the hotkeys currently defined for me, with some interesting (constructed!) conflicts.

See for example how Cmd P is connected to both opening the command palette, opening a daily note, and open the next daily note. Kind of stupid setup, so I need to fix that soon! :grin:

In addition one can see that for the first command, Navigate back, both Cmd Home and Opt ArrowLeft are valid combinations.

Whilst working with this we’ve got a FR re-opened, see A way to find which command is bound a specific hotkey, so please show some love to that, to get more attention to issues related to resolving hotkey conflicts, and to locate what a given command does.

I also found a plugin, see forum post in Show only assigned hotkeys - #3 by ichmoimeyo, which could display hotkeys on a visual image of the keyboard. Sadly, it’s in the early stages of development, and it doesn’t do the correct thing on Mac (as of today).

3 Likes