Anki Forums

Emacs-style shortcuts with "Ctrl+T, ..." in the editor in 45+

With emacs-style I mean a two part shortcut like “Ctrl+T, T”.

The following minimal add-on worked in 2.1.44 but in 2.1.45+ it breaks the built-in shortcuts for latex such as “Ctrl+T, T” (E/M):

from aqt import gui_hooks
from aqt.utils import tooltip

def shortcut_test(cuts, editor):
    cuts.append(("Ctrl+T, D", lambda: tooltip("test")))
gui_hooks.editor_did_init_shortcuts.append(shortcut_test)

As far as I see my code is similar to what other add-ons do.

My code seems to have broken with the changes in the editor from the beginning of May.

Is the problem my code or is it in Anki?

This is relevant for me because I use two part shortcuts as a default in my add-on Extended Tag Add/Edit Dialog. I’d like to keep a combination starting with Ctrl+T because Arthur also has a tag related add-on for med students named high yield tags that uses two part shortcuts that start with ctrl+t (actually after talking with ankingmed we decided to switch to these similar shortcuts at the same time last year).

The editor shortcuts are handled in JS now, so for shortcuts that share a common prefix, you’d need to listen for them in JS to avoid Qt swallowing the shortcut. AFAIK, this is not super easy at the moment as Anki is not exposing a utility to handle the multiple keystrokes.

@hengiesel I presume we won’t be able to export WithShortcut in the near future; but maybe we could expose registerShortcut for now?

I think we can export registerShortcut() generally. Not every shortcut needs to be bound to an UI element.
Maybe we could export new functions over the anki module exclusively though, making that transition smoother.

1 Like

Some more background info. Maybe my minimal example was too minimal. I actually didn’t use a hook but instead directly set the qt shortcut by wrapping a built-in function from addcards like this:

from anki.hooks import wrap
from aqt import mw
from aqt.addcards import AddCards
from aqt.utils import tooltip
from aqt.qt import *

# addHook("setupEditorShortcuts", SetupShortcuts) doesn't work when editor
# is not focused, e.g. if focus is on tag line.
def addAddshortcut(self, mw):
    shortcut = QShortcut(QKeySequence("Ctrl+T, D"), self)
    shortcut.activated.connect(lambda: tooltip("Hello"))
AddCards.__init__ = wrap(AddCards.__init__, addAddshortcut)

I thought that this should still work in 45+. I grepped the source code for “ctrl+t” and only found it in editor.py So I thought that the advancd dropdown menu is still drawn with pyqt, see here and that this would mean that setting a qt shortcut directly should work.

I don’t want to say that Anki should support this approach for add-ons. It’s just what I did. Maybe that’s relevant info for you.

In the meantime I’ve found TemplateButtons.svelte …

I don’t think onAdvanced() in editor.py is used anymore. I presume Henrik left it in to avoid add-ons throwing errors, though we should probably at least convert the functions to stubs and add a comment at one point to avoid leading people up the wrong path.

1 Like

The old code has had deprecation warnings placed on it, and WithShortcut is now available for use in add-ons, but the API is not stable yet: Using Svelte editor components from Anki - what causes "TypeError: ctx[3] is not a constructor"? - #5 by dae