Skip to content

a13/reverse-im.el

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reverse-im.el

https://melpa.org/packages/reverse-im-badge.svg https://img.shields.io/github/stars/a13/reverse-im.el.svg https://img.shields.io/github/issues/a13/reverse-im.el.svg https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg

Overrides function-key-map for preferred input-method(s) to translate input sequences to English, so we can use Emacs bindings while a non-default system layout is active.

Quick start

;; 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) ; fix a word in 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)
  (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 on

Installation and usage

Manual installation

M-x package-install RET reverse-im RET

Using use-package :ensure

Using provided minor mode instead (see Settings for details):

(use-package reverse-im
  :ensure t
  :custom
  (reverse-im-input-methods '("ukrainian-computer"))
  ;; (reverse-im-activate "ukrainian-computer") ; the legacy way
  :config
  (reverse-im-mode t))

Usage

Reverse-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 have which-key installed, you can examine how an input method will be remapped by calling

M-x reverse-im-which-key-show

Manual customization

NB: 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 RET

Since version 0.0.2 all possible bindings with Ctrl, Meta, and Super are translated. If you want to change it (e.g. you don’t use Super)

(setq reverse-im-modifiers '(control meta))
;; or
M-x customize-variable RET reverse-im-modifiers RET

Activation/Deactivation

M-x reverse-im-mode RET
;; or
(reverse-im-mode t) ; call with a negative argument to disable

Alternatively, you can directly call translation function:

(reverse-im-activate "ukrainian-computer")

Since version 0.0.3 it supports multiple input method translation:

(reverse-im-activate '("ukrainian-computer" "arabic"))

If something goes wrong or you just want to turn translation off.

M-x reverse-im-deactivate
;; or
(reverse-im-deactivate)
(reverse-im-deactivate t) ; to reset translation tables cache

Advising read-char

Reverse-im doesn’t work with custom dispatchers like org-export, org-capture , mu4e etc. You can try to fix it by advising read-char and read-char-exclusive. Do it on your own risk since the feature is experimental, hacky and wasn’t tested good enough.

There are two versions of advice functions - reverse-im-read-char-include (the less risky one) translates input iff current command matches (or equals) any element of customizable reverse-im-read-char-include-commands list, while reverse-im-read-char-exclude (the more risky one) translates input unless current command does match reverse-im-read-char-exclude-commands.

You can choose which one to use by customizing reverse-im-read-char-advice-function before reverse-im-mode is enabled (see Examples above) or by advicing read-char~/~read-char-exclusive manually.

(advice-add #'read-char-exclusive #'reverse-im-read-char-include)
(advice-add #'read-char #'reverse-im-read-char-include)

or

(advice-add 'read-char-exclusive #'reverse-im-read-char)
(advice-add 'read-char #'reverse-im-read-char)

If something goes wrong, remove the advices by

(advice-remove 'read-char-exclusive #'reverse-im-read-char-include)
(advice-remove 'read-char #'reverse-im-read-char-include)

or

(advice-remove 'read-char-exclusive #'reverse-im-read-char)
(advice-remove 'read-char #'reverse-im-read-char)

Char folding

./screenshots/char-fold.png 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))

pre-27 versions

You can download a new version of char-fold.el manually, or using something like

(use-package char-fold
  :custom
  (char-fold-symmetric t)
  (search-default-mode #'char-fold-to-regexp)
  :quelpa (char-fold :url "https://raw.githubusercontent.com/emacs-mirror/emacs/master/lisp/char-fold.el"
                     :fetcher url))

Interactive translation

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

./screenshots/avy.png

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.

Known issues:

  • 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 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) don’t work with in Hydra