Emacs, Linux and international keyboard layouts

后端 未结 5 1355
太阳男子
太阳男子 2020-12-25 14:32

Is there an easy way to use Emacs key-bindings when you are using a not-English (Russian) keyboard layout?

Whenever an international layout is on, all keystrokes are

5条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-25 14:56

    Here is an alternative solution that uses the OS language, based on syndikat's answer.

    Some key translations are missing, but it should be easy to add them.

    ;; USAGE:
    ;; Put in your .emacs:
    ;; 
    ;; (translate-keystrokes-ru->en)
    ;; (add-hook 'text-mode-hook
    ;;           (lambda () (literal-insert-mode 1)))
    ;; 
    ;; Only buffers with literal-insert-mode active will be sensitive to the
    ;; environment language. Prefixed keybindings will still be usable.
    
    (defun translate-keystrokes-ru->en ()
      "Make emacs output english characters, regardless whether
    the OS keyboard is english or russian"
      (flet ((make-key-stroke (prefix char)
               (eval `(kbd ,(if (and (string-match "^C-" prefix)
                                     (string-match "[A-Z]" (string char)))
                                (concat "S-" prefix (string (downcase char)))
                                (concat prefix (string char)))))))
        (let ((case-fold-search nil)
              (keys-pairs (mapcar* 'cons
                                   "йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖ\ЭЯЧСМИТЬБЮ№"
                                   "qwertyuiop[]asdfghjkl;'zxcvbnm,.QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>#"))
              (prefixes '(""    "s-"    "M-"    "M-s-"
                          "C-"  "C-s-"  "C-M-"  "C-M-s-")))
          (mapc (lambda (prefix)
                  (mapc (lambda (pair)
                          (define-key key-translation-map
                              (make-key-stroke prefix (car pair))
                            (make-key-stroke prefix (cdr pair))))
                        keys-pairs))
                prefixes))))
    
    (defun literal-insert ()
      (interactive)
      (insert-char last-input-event 1))
    
    (define-minor-mode literal-insert-mode
        "Make emacs output characters corresponging to the OS keyboard,
     ignoring the key-translation-map"
      :keymap (let ((new-map (make-sparse-keymap))
                    (english-chars "qwertyuiop[]asdfghjkl;'zxcvbnm,.QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>#"))
                (mapc (lambda (char)
                        (define-key new-map (string char)
                          'literal-insert))
                      english-chars)
                new-map))
    

提交回复
热议问题