How to avoid redefining hotkeys?

What I’m trying to do

I’m trying to find an available key to link some new (or old) functionality to a hotkey, but I don’t want to overwrite existing stuff unintentionally.

Things I have tried

I’ve tried intentionally to overwrite a hotkey to see if I would get some warning, which I didn’t. Obsidian happily allowed me to assign cmd+P to multiple commands.

Tried searching for a command to list hotkeys, even tried doing the hotkey in the search filed of hotkeys. But no luck.

I did however find that Obsidian says it conflicts, but not any advise on how to avoid the conflicts, or finding the conflicts. The image below was captured when I hovered over the last definition.
image

I tried searching for resolving hotkey conflicts, which lead to some feature requests. One which is looping and is closed: A way to see what functions hotkeys are mapped to, and another one, Sort hotkeys to the top, which doesn’t seem to get any more focus, or is that just me not knowing how to look for that?

So my current workaround would seem to be to hover over the hotkey, and if there is a conflict, I need to do a multi-line search in .obsidian/hotkeys.json and convert stuff like Cmd (or possibly Ctrl) to something like “Mod”, just to find a textual reference, which is not the same as in the Hotkeys settings, for the multiple definition of a given key. Kind of hard…

In other words; Are there any progress on any features related to avoiding redefinition of hotkeys? Or are there better methods to resolve hotkey conflicts?

1 Like

Don’t conflicts show immediately in red?

Any use?

Commands by hotkey

```dataviewjs

const getNestedObject = (nestedObj, pathArr) => {
    return pathArr.reduce((obj, key) =>
        (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}

function hilite(keys, how) {
    // need to check if existing key combo is overridden by undefining it
    if (keys && keys[1][0] !== undefined) {
        return how + keys.flat(2).join(' ').replace('Mod', 'CMD').replace('Alt', 'OPT').replace('Ctrl', 'CTRL').replace('Shift', 'SHIFT').replace('Enter', 'ENTER') + how;
    } else {
        return how + '–' + how;
    }
}

function getHotkey(arr, highlight=true) {
    let hi = highlight ? '**' : '';
    let defkeys = arr.hotkeys ? [[getNestedObject(arr.hotkeys, [0, 'modifiers'])],
    [getNestedObject(arr.hotkeys, [0, 'key'])]] : undefined;
    let ck = app.hotkeyManager.customKeys[arr.id];
    var hotkeys = ck ? [[getNestedObject(ck, [0, 'modifiers'])], [getNestedObject(ck, [0, 'key'])]] : undefined;
    return hotkeys ? hilite(hotkeys, hi) : hilite(defkeys, '');
}

let cmds = dv.array(Object.entries(app.commands.commands))
    .where(v => getHotkey(v[1]) != '–')
    .sort(v => v[1].id, 'asc')
    .sort(v => getHotkey(v[1], false), 'asc');

dv.paragraph(cmds.length + " hotkeys. " +
    "User-defined hotkeys in <strong>bold</strong>.<br><br>");

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

Commands by command name

```dataviewjs

const getNestedObject = (nestedObj, pathArr) => {
    return pathArr.reduce((obj, key) =>
        (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}

function hilite(keys, how) {
    // need to check if existing key combo is overridden by undefining it
    if (keys && keys[1][0] !== undefined) {
        return how + keys.flat(2).join(' ').replace('Mod', 'CMD').replace('Alt', 'OPT').replace('Ctrl', 'CTRL').replace('Shift', 'SHIFT').replace('Enter', 'ENTER') + how;
    } else {
        return how + '–' + how;
    }
}

function getHotkey(arr, highlight=true) {
    let hi = highlight ? '**' : '';
    let defkeys = arr.hotkeys ? [[getNestedObject(arr.hotkeys, [0, 'modifiers'])],
    [getNestedObject(arr.hotkeys, [0, 'key'])]] : undefined;
    let ck = app.hotkeyManager.customKeys[arr.id];
    var hotkeys = ck ? [[getNestedObject(ck, [0, 'modifiers'])], [getNestedObject(ck, [0, 'key'])]] : undefined;
    return hotkeys ? hilite(hotkeys, hi) : hilite(defkeys, '');
}

let cmds = dv.array(Object.entries(app.commands.commands))
    .sort(v => v[1].id, 'asc');

dv.paragraph(cmds.length + " commands. " +
    "User-defined hotkeys in <strong>bold</strong>.<br><br>");

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

Kind of?
image

On my screen that is not very clear, and it doesn’t show the conflicting setup.

If only it had shown those with either a conflicting key combination, and/or multiple key configurations. It seems to miss out on those cases. But other than that, it’s a nifty little script.

1 Like

Some questions related to @anon63144152 script, and potential issues, (or just me misreading your code):

  1. Could the missing cases of conflict multiple locations be related to the ternary return operation within getHotkey which either returns a key from custom key bindings or from default bindings, and thusly ignoring it might be in both?

  2. Am I correct in assuming that getHotkey() is called three times for each command? Two in the let cmds part, and once in the cmds.map part?

  3. Related to 2., is it possible to do a dataviewjs query using as clauses/aliases, and then do a sort related to that alias?

1 Like

I resurrected this FR A way to find which command is bound a hotkey

1 Like

I apologise for this answer in advance: a friend shared this code with me when they convinced me to switch from Scrivener to Obsidian. I just asked them where they got it from, and they said ‘the forum’ and sent this link:

I don’t know enough to be able to answer your questions but perhaps you can get some answers on the other thread.

Thanks @anon63144152 for making me aware of that link. Since I didn’t see the answers to my questions, I then proceeded to resolve most of them myself, and posted a reply on the other thread. See link below:

I’m also glad @WhiteNoise resurrected the FR, so that it might evolve into something which in the future would render these queries useless, as one could then do a search for say cmd + p.

Finally I found, that occasionally, and I don’t why or when, Obsidian does actually report where the conflicting hotkey is. Alas, it completely fails, when some idiotyou assign the same key combination to more than two commands.

So, all in all, I reckon I’m good to go, and still hoping for the FR to be resolved.

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.