vkbo / novelWriter

novelWriter is an open source plain text editor designed for writing novels. It supports a minimal markdown-like syntax for formatting text. It is written with Python 3 (3.9+) and Qt 5 (5.15) for cross-platform support.
https://novelwriter.io
GNU General Public License v3.0
2.05k stars 106 forks source link

Adjustable shortcut keybinds #740

Open MatthewMarinets opened 3 years ago

MatthewMarinets commented 3 years ago

My use case

I make frequent use of alt-codes when typing, especially for characters like "«»". Right now, you can't use any alt-code that includes the digits 1-4, because that's the shortcut for changing views. Qt already supports alt-codes, as I can type any code that doesn't include 1-4, but I will never be able to do e.g. ♥ (alt+3), which is a little heartless.

Possible solutions

The simplest solution is to just change the current view-changing hotkeys to something else; I'm going to experiment with changing it to ctrl+alt+1-4 locally after writing this up, but I'd consider this a temporary solution and likely disruptive to other users who don't need my use-case and prefer the old hotkeys.

Personally, I would angle for adjustable hotkeys. If you want extreme polish, you could make a whole UI window that lists all the bindable actions and lets us adjust the hotkey in the menu. On the opposite end, I'd consider it entirely reasonable to just make a hotkeys.txt file that can be used to change the hotkeys on startup. A quick search on the codebase shows .setShortcut() is called 89 times.

I'm not familiar enough with Qt and GUI design to judge how hard making a new window would be, so I'll quickly analyze the hotkeys file approach and let you decide if it sounds sensible.

Simple Example (hotkeys file approach)

    # View > TreeView
    self.aFocusTree = QAction("Focus Project Tree", self)
    self.aFocusTree.setStatusTip("Move focus to project tree")
    self.aFocusTree.setShortcut("Alt+1")
    self.aFocusTree.triggered.connect(lambda: self.theParent.switchFocus(nwWidget.TREE))
    self.viewMenu.addAction(self.aFocusTree)

Would get an entry in hotkeys.txt like:

"Focus Project Tree": "Alt+1";

After reading the file into a dict named hotkeys, the code becomes:

    # View > TreeView
    action_name = "Focus Project Tree"
    shortcut = hotkeys.get(action_name, "Alt+1")
    # set the shortcut to default if it's invalid
    self.aFocusTree = QAction(action_name, self)
    self.aFocusTree.setStatusTip("Move focus to project tree")
    self.aFocusTree.setShortcut(shortcut)
    self.aFocusTree.triggered.connect(lambda: self.theParent.switchFocus(nwWidget.TREE))
    self.viewMenu.addAction(self.aFocusTree)

Disadvantages (hotkeys file approach)

While on the surface rebindable keys are simple, there's a few edge cases that can result in some feature creep.

vkbo commented 3 years ago

Yeah, novelWriter is written with Linux in mind, so the quirky Alt+number approach on Windows hasn't really crossed my mind. I don't really want to write a customiseable shortcut tool until I really have to. I'd rather just change those shortcuts or redirect or disable them on windows.

MatthewMarinets commented 3 years ago

I'm not sure even that many Windows users use alt-codes, which is why I leaned my proposal so far toward customizability rather than just changing things. I still think it's really simple to have a textfile that can customize hotkeys if you just make it clear that edge cases like multiple hotkeys linked to the same shortcut aren't dealt with specially, I know big-name games and enterprise software that doesn't deal with that case.

MatthewMarinets commented 3 years ago

There's only six hotkeys that use alt+something: focus tree, editor, right pane, outline; and right-pane history back and forward. I changed them all locally to use ctrl+alt and things work for me now. Again, pushing this to everyone may be disruptive for those used to the old keys. At the very least, I can confirm that this simple fix works as expected, and it only requires changing 6 lines (could be done with four, ctrl+left/right don't have to be remapped).

Also pulled latest code before making this change, and just wanted to say thanks for making big files load so much faster. I was shocked by how big the improvement was ♥.

vkbo commented 3 years ago

If I'm making customised keybindings, I will probably make a GUI settings tool for it. Which isn't a big job, but still takes a bit of effort. I'll keep it in mind.

I've tried to stick to established standard shortcuts where possible, and in some cases they are different depending on OS. Changing the focus shortcuts to Ctrl+Alt on Windows isn't a big deal but it may be a bit disruptive as you say. I'll think about it.

Also pulled latest code before making this change, and just wanted to say thanks for making big files load so much faster. I was shocked by how big the improvement was .

The bottle neck is the spell checker, and your Preferences is probably set to the internal one, which is slow and not very good. The Spell Enchant spell checker is much faster. I did make a speed improvement to the internal one a while back though.

You can also specify a limit for how large documents in kB the editor will automatically spell check. When automatic spell check is off, it checks spelling as you type instead.

vkbo commented 3 years ago

From version 1.4 (just made a beta release of 1.4) the focus shortcuts will use Ctrl+Alt+1 etc on Windows.

As for the editable shortcuts, I will keep this issue open for later. I do intend to implement it at some point.