diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 248084c..7b529bf 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -14,8 +14,11 @@ jobs: fail-fast: false matrix: emacs_version: + - 26.1 - 26.3 - - 27.2 + - 27.1 + - 28.2 + - 29.1 ignore_warnings: - true include: diff --git a/README.org b/README.org index 8b7de95..6cf5a3c 100644 --- a/README.org +++ b/README.org @@ -174,5 +174,7 @@ ** Known issues: - Bindings with AltGr (as Meta) [[https://github.com/a13/reverse-im.el/issues/4#issuecomment-308143947][don't work]] well on Windows. - - Single key shortcuts (i.e. without modifiers) [[https://github.com/a13/reverse-im.el/issues/17][don't work with]] in Hydra and some other modes (~org-agenda~). - [[https://github.com/a13/reverse-im.el/issues/21][Doesn't]] [[https://github.com/a13/reverse-im.el/issues/6][work]] well for punctuation keys if they are placed on different keys than in English layout. + - "Buffer is read-only:" error + Reverse-im doesn't work for /self-insert-command/ (obviously), but in read-only modes one may want to use single key shortcuts. In this case it's possible to /suppress-keymap/ to undefine /self-insert-command/, so /function-key-map/ override it's behavior. + - Single key shortcuts (i.e. without modifiers) [[https://github.com/a13/reverse-im.el/issues/17][don't work with]] in Hydra diff --git a/reverse-im-test.el b/reverse-im-test.el index 9a59ac5..b9f03c0 100644 --- a/reverse-im-test.el +++ b/reverse-im-test.el @@ -8,13 +8,10 @@ (seq-set-equal-p s1 s2 'equal)))) (ert-deftest reverse-im--modifiers-combos-test () - (if (string= "26.3" emacs-version) - (should (equal (reverse-im--modifiers-combos '(control meta)) - '(nil (control) (meta) (meta control)))) - (should - (seq-set-equal-deep-p - (reverse-im--modifiers-combos '(meta control)) - '(nil (meta) (control) (control meta))))) + (should (equal (sort (mapcar (apply-partially #'format "%s") + (reverse-im--modifiers-combos '(control meta))) + #'string<) + '("(control)" "(meta control)" "(meta)" "nil"))) (should (equal (reverse-im--modifiers-combos '()) @@ -45,7 +42,7 @@ (ert-deftest reverse-im--im-to-pairs-test () (should (equal - (reverse-im--im-to-pairs "russian-computer") + (reverse-im--im-to-pairs quail-keyboard-layout "russian-computer") '((62 1070) (60 1041) (77 1068) (78 1058) (66 1048) (86 1052) (67 1057) (88 1063) (90 1071) (34 1069) (58 1046) (76 1044) (75 1051) (74 1054) (72 1056) (71 1055) (70 1040) (68 1042) (83 1067) (65 1060) (125 1066) @@ -60,7 +57,7 @@ (ert-deftest reverse-im-sanity-test () (let ((reverse-im--keymaps-alist nil)) (should (mapcar (lambda (m) - (reverse-im--im-to-pairs (car m))) + (reverse-im--im-to-pairs quail-keyboard-layout (car m))) input-method-alist)) (should (mapcar (lambda (m) (reverse-im--im-to-keymap (car m))) diff --git a/reverse-im.el b/reverse-im.el index f667799..87101a6 100644 --- a/reverse-im.el +++ b/reverse-im.el @@ -1,6 +1,7 @@ ;;; reverse-im.el --- Reverse mapping for non-default system layouts -*- lexical-binding: t -*- -;; Authors: Juri Linkov (initial idea), Dmitry K. (packager and maintainer) +;; Author: Juri Linkov (initial idea) +;; Maintainer: DK ;; Package-Requires: ((emacs "25.1") (seq "2.23")) ;; Keywords: i18n ;; Homepage: https://github.com/a13/reverse-im.el @@ -20,10 +21,10 @@ ;; see . ;;; Commentary: -;; Overrides `function-key-map' parent for preferred input-method -;; to translate input sequences the default system layout (english) -;; so we can use Emacs bindings while non-default system layout is active. +;; Override the parent keymap of `function-key-map' for the preferred input method +;; to translate input sequences to the default system layout (English), so we can +;; use Emacs bindings while the non-default system layout is active. ;; Usage example: ;; (use-package reverse-im ;; :ensure t @@ -32,8 +33,8 @@ ;; :config ;; (reverse-im-mode t)) -;; or, alternatively, add the library to your load-path and -;; (reverse-im-activate "ukrainian-computer") manually +;; or, alternatively, add the library to your `load-path' +;; and (reverse-im-activate "ukrainian-computer") manually ;;; Code: @@ -68,7 +69,7 @@ (defcustom reverse-im-avy-action-char ?T - "Char for avy-action-reverse-im-translate." + "Char for `reverse-im-avy-action-translate'. Set to nil to turn avy action off." :type 'character :group 'reverse-im) @@ -107,19 +108,20 @@ ;;; Utils (defun reverse-im--modifiers-combos (modifiers) - "All combinations of MODIFIERS from the list argument." + "Return all combinations of MODIFIERS. See also `reverse-im-modifiers'." (seq-reduce (lambda (acc x) (append acc (mapcar (apply-partially #'cons x) acc))) (seq-uniq modifiers) '(nil))) -(defun reverse-im--sanitize-p (translation) - "Check if we should do TRANSLATION." +(defun reverse-im--sanitize-p (layout translation) + "Check if we should do TRANSLATION for LAYOUT." (seq-let (keychar from) translation + ;; `keychar' and `from' should be different characters (and (characterp from) (characterp keychar) (/= from keychar) - ;; don't translate if the char is in default layout - (not (member from (append quail-keyboard-layout nil)))))) + ;; `from' shouldn't be in the `layout' + (not (member from (append layout nil)))))) (defun reverse-im--add-mods (modifiers key) "Generate a single translation binding adding MODIFIERS to KEY." @@ -141,7 +143,7 @@ (kill-buffer quail-completion-buf)) (and current-input-method quail-keyboard-layout - (quail-map)))) + (cdr (quail-map))))) (defun reverse-im--to-char (x) "Convert X to char, if needed." @@ -164,11 +166,13 @@ (cdr translated)))))))) ;; to test more easily -(defun reverse-im--im-to-pairs (input-method) - "Generate a list of translation pairs for INPUT-METHOD." - (let* ((qm (reverse-im--im-to-quail-map input-method)) - (normalized (mapcan #'reverse-im--normalize-keydef (cdr qm)))) - (seq-filter #'reverse-im--sanitize-p normalized))) +(defun reverse-im--im-to-pairs (layout input-method) + "Generate a list of translation pairs for INPUT-METHOD using LAYOUT." + (thread-last input-method + reverse-im--im-to-quail-map + (mapcan #'reverse-im--normalize-keydef) + (seq-filter (apply-partially #'reverse-im--sanitize-p layout)))) + ;;; Generate the translation keymap (defun reverse-im--im-to-keymap (input-method) @@ -177,7 +181,7 @@ (let ((input-method (intern input-method))) (or (alist-get input-method reverse-im--keymaps-alist) ;; generate translation pairs - (let* ((filtered (reverse-im--im-to-pairs input-method)) + (let* ((filtered (reverse-im--im-to-pairs quail-keyboard-layout input-method)) ;; add all modifiers (tt (mapcan #'reverse-im--key-def-internal filtered)) (translation-keymap (make-sparse-keymap))) @@ -387,7 +391,7 @@ current object." (defun reverse-im-translate-word (arg) "Translate word before the point. With prefix ARG translates ARG words instead of the last one, if ARG is 0 - translate until the beginning of line." (interactive "p") - (if (eq 0 arg) + (if (zerop arg) (reverse-im--translate-subr #'move-beginning-of-line 1) (reverse-im--translate-subr #'backward-word arg)))