Are you using a non-Latin keyboard layout? Have you ever seen Emacs display a message such as “C-є is undefined” instead of executing a desired command? If so, then this package is probably for you!
💡 It’s just a collection of hacks, and definitely not a magic bullet, so if you have any issues, please take a look at known ones first.
💡 I use use-package for all the examples here. Since it’s a built-in feature of the latest version of Emacs, they should work fine there.
(use-package reverse-im
:ensure t ; install `reverse-im' using package.el
:demand t ; always load it
;; translate these methods, use M-x `list-input-methods'
;; if you're not sure which one to use
(reverse-im-input-methods '("ukrainian-computer"))
:config
(reverse-im-mode t)) ; turn the global minor mode on💡 See below for details.
;; Needed for `:after char-fold' to work
(use-package char-fold
:custom
(char-fold-symmetric t)
(search-default-mode #'char-fold-to-regexp))
(use-package reverse-im
:ensure t ; install `reverse-im' using package.el
:demand t ; always load it
:after char-fold ; but only after `char-fold' is loaded
:bind
("M-T" . reverse-im-translate-word) ; to fix a word written in the wrong layout
:custom
;; cache generated keymaps
(reverse-im-cache-file (locate-user-emacs-file "reverse-im-cache.el"))
;; use lax matching
(reverse-im-char-fold t)
;; advice read-char to fix commands that use their own shortcut mechanism
(reverse-im-read-char-advice-function #'reverse-im-read-char-include)
;; translate these methods
(reverse-im-input-methods '("ukrainian-computer"))
:config
(reverse-im-mode t)) ; turn the mode onThese examples should be sufficient in most cases. However, if you need to go deeper:
This one is for Package.el users. Straight and Elpaca users should already know how to do this.
M-x package-install RET reverse-im RETReverse-im provides a simple minor mode that activates/deactivates translations for all
input methods from (customizable) reverse-im-input-methods list (empty by default).
If you use which-key (a built-in feature in the latest Emacs versions), you can examine how an input method will be remapped by calling
M-x reverse-im-which-key-show💡 I highly recommend the use-package method.
;; standard customization interface, note that this will turn on the mode immediately
M-x customize-variable RET reverse-im-input-methods RET
;; These store list variable in `custom-file'.
;; provides auto-completion, one input-method at a time
M-x reverse-im-add-input-method RET ukrainian-computer RETSince version 0.0.2 all possible bindings with Ctrl, Meta, and Super are translated. If you want to change the behavior, for example, if you don’t use Super,
(setq reverse-im-modifiers '(control meta))
;; or
M-x customize-variable RET reverse-im-modifiers RETM-x reverse-im-mode RET
;; or
(reverse-im-mode t) ; call with a negative argument to disableAs an alternative, you can call the translation function directly. Since version 0.0.3, it has supported multiple input methods.
(reverse-im-activate '("ukrainian-computer" "arabic"))If something goes wrong, or if you simply want to turn the translation off,
M-x reverse-im-deactivate
;; or
(reverse-im-deactivate)
(reverse-im-deactivate t) ; to reset the translation tables cache💡 This feature since is experimental, hacky and wasn’t tested good enough, so use it on your own risk.
Some commands such as org-export, org-capture, and mu4e, use custom dispatchers, don’t work out of the box in a non-latin layout.
Fortunately most of them use read-char or read-char-exclusive for reading input, so we can advice the function to translate input characters. The simplest way is to set reverse-im-read-char-advice-function defcustom, though you can advice then #manually if you want to.
There are two possible values - reverse-im-read-char-include (the less risky one) translates the input iff current command matches (or equals) any element in the customizable reverse-im-read-char-include-commands list. The more lazy (and risky) version reverse-im-read-char-exclude translates the input unless the current command matches any element in the reverse-im-read-char-exclude-commands.
💡 set these before reverse-im-mode is enabled, or advice the functions manually
(advice-add #'read-char-exclusive :around #'reverse-im-read-char-include)
(advice-add #'read-char :around #'reverse-im-read-char-include)or
(advice-add 'read-char-exclusive :around #'reverse-im-read-char)
(advice-add 'read-char :around #'reverse-im-read-char)
Emacs supports Lax Matching During Searching and since version 27 you can include your own search substitutions. Reverse-im adds substitutions to char-fold-include generated using reverse-im-char-fold-include if reverse-im-char-fold is set to t (before reverse-im-mode is activated).
(use-package char-fold
:custom
(char-fold-symmetric t)
(search-default-mode #'char-fold-to-regexp))If you want to fix a region or a word which was typed using incorrect layout, you can use interactive functions reverse-im-translate-region and reverse-im-translate-word respectively.
Avy integration
If avy is installed, reverse-im adds avy-action-reverse-im-translate to avy-dispatch-alist (bound to reverse-im-avy-action-char, ?T is default one), so it’s possible to translate words and lines which are you jumping to. To disable the functionality reverse-im-avy-action-char should be set to nil.
Reverse-im overrides function-key-map for preferred input-method(s) to translate input sequences. The original idea came from this blog post by Juri Linkov.
- Bindings with AltGr (as Meta) don’t work well on Windows.
- Doesn’t 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 sometimes one may want to use single key shortcuts in read-only modes. In this case it’s possible tosuppress-keymapto undefineself-insert-command, sofunction-key-mapoverrides its behavior. - Single key shortcuts (i.e. without modifiers) don’t work with in Hydra
