xahlee / xah-fly-keys

the most efficient keybinding for emacs
http://xahlee.info/emacs/misc/xah-fly-keys.html
472 stars 80 forks source link

-- no kidding, xah-fly-keys leader & prefix stuff has a qwerty (and other keyboard layouts) bug, it seems that only dvorak is actually getting the mnemonics. Also: Solution provided. #69

Open DanLanglois opened 5 years ago

DanLanglois commented 5 years ago

In this:

https://github.com/xahlee/xah-fly-keys/issues/67

I gave this info:

I run Xah-fly-keys.

Then, if I hit SPC, the leader key, I see this emacs-which-key popup:

DEL -- xah-fly-insert-mode-activat.. RET -- execute-extended-command SPC -- xah-fly-insert-mode-active.. TAB -- +xah-fly--tab-key-map ' -- xah-show-formfeed-as-line , -- +xa-fly-w-keymap 3 -- delete-window 4 -- split-window-right 5 -- balance-windows 6 -- xah-upcase-sentence 9 -- ispell-word ; -- save-buffer \ -- toggle-input-method a -- mark-whole-buffer b -- xah-toggle-previous-letter-.. c -- xah-copy-all-or-region d -- +xah-fly-e-keymap e -- +xah-fly-dot-keymap

I think in terms, here, of providing great discoverability by popping up a buffer with options when you start typing a command.

However, I look again at this and realize that part of the issue, or at least an issue, is that the dvorak-to-qwerty conversion may not be happening for prefix stuff. Note this part: 'a -- mark-whole-buffer'. That is correct. And 'a' is the same in qwerty and dvorak. This doesn't seem likely to be a coincidence, when we consider this: 'd -- +xah-fly-e-keymap'. Oops! It could be a dvorak-to-qwerty fail.

So can this fixed? Well, you're already successfully converting in the other direction, so this is not hopeless. A rather simple-minded 'fix' would be to convert from from dvorak to querty, backwards, before letting the code take over and do what it already is doing, converting from querty to dvorak. That is two steps, to get an outcome of zero steps. So maybe the better idea is to comment out some existing code. Somebody is calling the function xah-fly--key-char, when they're not supposed to bother. Note this:

(defun xah-fly--define-keys (@keymap-name @key-cmd-alist) (interactive) (mapc (lambda ($pair) (define-key @keymap-name (kbd (xah-fly--key-char (car $pair))) (cdr $pair))) @key-cmd-alist))

So okay, you need two versions of this function. Most of the time you need the other version. I think the only exception is when you make the 'command' keys. Also the 'insert' keys, but there are not actually any 'insert' keys, or that is, we don't worry about shadowing the insert keys. Anyways, because the 'other' version is mostly what needs to be used, I changed the name of this one, and made a new version with this old name -- defun xah-fly--define-keys. The old function is now called xah-fly--define-keys-for-keyboard-layout, because does not default to dvorak. Remember, the problem with that is we lose our mnemonics in the prefixes, like in this function -- xah-fly-e-keymap. You don't want to be hitting 'd' for this, on a qwerty keyboard. Here is my new function (but which retains the old name):

(defun xah-fly--define-keys (@keymap-name @key-cmd-alist) "Map `define-key' over a alist @key-cmd-alist. This is the naive version of the function, which preserves mnemonics irrespective of local keyboard layout. Example usage: ;; (xah-fly--define-keys ;; (define-prefix-command 'xah-fly-dot-keymap) ;; '( ;; (\"h\" . highlight-symbol-at-point) ;; (\".\" . isearch-forward-symbol-at-point) ;; (\"1\" . hi-lock-find-patterns) ;; (\"w\" . isearch-forward-word))) Version 2019-02-12" (interactive) (mapc (lambda ($pair) (define-key @keymap-name (kbd (car $pair)) (cdr $pair)))
;; (define-key @keymap-name (kbd (xah-fly--key-char (car $pair))) (cdr $pair))) @key-cmd-alist))

I'm checking it in, then. Tested: working. See pull request:

https://github.com/xahlee/xah-fly-keys/pull/66

gcentauri commented 5 years ago

there was some conversation about this some time ago #33 - I am in support to use finger positions, but I'm not sure the different considerations here. I'm curious about your fix to just rename them programmatically, I will check it out.