Emacs 如何确定键盘布局

10

Emacs是否可以检测当前的键盘布局?

我经常在英语和德语之间切换(Win操作系统)的键盘布局来编写文本。然而,一些功能(例如C-Y)应该始终位于相同的物理按键上,无论我当前输入的语言是什么。

谢谢

1个回答

4
考虑使用M-x set-input-methodM-x toggle-input-method。切换绑定到C-\,设置绑定到C-x RET C-\。如果您有超键,我建议使用这个绑定(global-set-key [?\H-\\] 'set-input-method)
如果您不是要问如何在不同的语言中输入,而是想知道如何在使用不同语言时让多个命令起作用,请尝试将它们绑定。在俄语符号上效果很好。有一天黑夜我甚至写了一个。
(setq russian-symbols '(
                         (?й . ?q)
                         (?ц . ?w)
                         (?у . ?e)
                         (?к . ?r)
                         (?е . ?t)
                         (?н . ?y)
                         (?г . ?u)
                         (?ш . ?i)
                         (?щ . ?o)
                         (?з . ?p)
                         (?х . ?\[)
                         (?ъ . ?\])
                         (?ф . ?a)
                         (?ы . ?s)
                         (?в . ?d)
                         (?а . ?f)
                         (?п . ?g)
                         (?р . ?h)
                         (?о . ?j)
                         (?л . ?k)
                         (?д . ?l)
                         (?ж . ?\;)
                         (?э . ?')
                         (?я . ?z)
                         (?ч . ?x)
                         (?с . ?c)
                         (?м . ?v)
                         (?и . ?b)
                         (?т . ?n)
                         (?ь . ?m)
                         (?б . ?,)
                         (?ю . ?.)

                         (?Й . ?Q)
                         (?Ц . ?W)
                         (?У . ?E)
                         (?К . ?R)
                         (?Е . ?T)
                         (?Н . ?Y)
                         (?Г . ?U)
                         (?Ш . ?I)
                         (?Щ . ?O)
                         (?З . ?P)
                         (?Х . ?{)
                         (?Ъ . ?})
                         (?Ф . ?A)
                         (?Ы . ?S)
                         (?В . ?D)
                         (?А . ?F)
                         (?П . ?G)
                         (?Р . ?H)
                         (?О . ?J)
                         (?Л . ?K)
                         (?Д . ?L)
                         (?Ж . ?:)
                         (?Э . ?\")
                         (?Я . ?Z)
                         (?Ч . ?X)
                         (?С . ?C)
                         (?М . ?V)
                         (?И . ?B)
                         (?Т . ?N)
                         (?Ь . ?M)
                         (?Б . ?<)
                         (?Ю . ?>)

                         (?Ё . ?~)
                         (?ё . ?`)
                         ))

(setq russian-symbols-full (append russian-symbols
                             '((?. . ?/)
                             (?, . ??)
                             (?\" . ?@)
                             (?№ . ?#)
                             (?\; . ?$)
                             (?: . ?^)
                             (?\? . ?&))))
(defun cm-ru-to-en-string(string)
  (apply 'concat (mapcar (lambda (arg) (setq arg (format "%c" (or (cdr (assoc arg russian-symbols-full)) arg)))) string)))

(defun cm-en-to-ru-string(string)
  (apply 'concat (mapcar (lambda (arg) (setq arg (format "%c" (or (car (rassoc arg russian-symbols-full)) arg)))) string)))

(defun cm-ru-to-en-region()
  (interactive)
  (let ((text (buffer-substring-no-properties (mark) (point))))
    (delete-region (mark) (point))
    (insert (cm-ru-to-en-string text))))

(defun cm-en-to-tu-region()
  (interactive)
  (let ((text (buffer-substring-no-properties (mark) (point))))
    (delete-region (mark) (point))
    (insert (cm-en-to-ru-string text))))

;; DO NOT USE vvv SINCE YOU WILL NOT BE ABLE TO INPUT THROUGH C-\

;; (let ((symbols russian-symbols))
;;   (while symbols
;;     (global-set-key (vector (car (car symbols))) (vector (cdr (car symbols))))
;;     (setq symbols (cdr symbols))))

;; DO NOT USE ^^^ SINCE YOU WILL NOT BE ABLE TO INPUT THROUGH C-\

;; (- ?\C-ы ?ы) ;;russian C-
;; (- ?\C-s ?s) ;;english C-
;; (- ?\M-ы ?ы) ;;russian M-
;; (- ?\M-s ?s) ;;english M-


(setq russian-symbols-map1
  (append 
    (mapcar (lambda (arg) (setq arg (cons (+ (- ?\C-ы ?ы) (car arg)) (+ (- ?\C-s ?s) (cdr arg))))) russian-symbols)
    (mapcar (lambda (arg) (setq arg (cons (+ (- ?\M-ы ?ы) (car arg)) (+ (- ?\M-s ?s) (cdr arg))))) russian-symbols)
    (mapcar (lambda (arg) (setq arg (cons (+ (- ?\C-\M-ы ?ы) (car arg)) (+ (- ?\C-\M-s ?s) (cdr arg))))) russian-symbols)
    (mapcar (lambda (arg) (setq arg (cons (+ (- ?\H-ы ?ы) (car arg)) (+ (- ?\H-s ?s) (cdr arg))))) russian-symbols)
    (mapcar (lambda (arg) (setq arg (cons (+ (- ?\H-\C-ы ?ы) (car arg)) (+ (- ?\H-\C-s ?s) (cdr arg))))) russian-symbols)
    (mapcar (lambda (arg) (setq arg (cons (+ (- ?\H-\M-ы ?ы) (car arg)) (+ (- ?\H-\M-s ?s) (cdr arg))))) russian-symbols)
    (mapcar (lambda (arg) (setq arg (cons (+ (- ?\H-\C-\M-ы ?ы) (car arg)) (+ (- ?\H-\C-\M-s ?s) (cdr arg))))) russian-symbols)))

(setq russian-symbols-map2
  (append
    russian-symbols-map1
    russian-symbols)) ; We must not start with russian letters, but if it is element in a sequence - in should be fine.

(setq symbols2 russian-symbols-map1)    ; One-key sequence command.
(let ((symbols2 russian-symbols-map1))
    (while symbols2
      (if
        (and (symbolp (lookup-key global-map
                        (vector
                          (cdr (car symbols2))
                          )))
          (lookup-key global-map
            (vector
              (cdr (car symbols2))
              )))
        (global-set-key
          (vector
            (car (car symbols2))
            )
          (lookup-key global-map
            (vector
              (cdr (car symbols2))
              ))))
      (setq symbols2 (cdr symbols2))))



(let ((symbols1 russian-symbols-map2) (symbols2 russian-symbols-map1)) ; Two keys sequence
  (while symbols1
    (while symbols2
      (if
        (and (symbolp (lookup-key global-map
                        (vector
                          (cdr (car symbols2))
                          (cdr (car symbols1))
                          )))
          (lookup-key global-map
            (vector
              (cdr (car symbols2))
              (cdr (car symbols1))
              )))
        (global-set-key
          (vector
            (car (car symbols2))
            (car (car symbols1))
            )
          (lookup-key global-map
            (vector
              (cdr (car symbols2))
              (cdr (car symbols1))
              ))))
      (setq symbols2 (cdr symbols2)))
    (setq symbols2 russian-symbols-map1)
    (setq symbols1 (cdr symbols1))))

(provide 'shamanizm) ;russian emacs-users should lol reading this

它能够工作。我已经绑定了所有带有俄语符号的全局热键,包括2级。

我现在没有使用它,因为它会占用启动时间,并且会使我的*Help*变得难以阅读,出现像It is bound to C-x b, C-x и, C-ч b, C-ч и这样的奇怪事情。请明智地使用它。


2
我对你的代码并没有深入的了解,但我认为这与我的问题无关。对于俄语,你有完全不同的字符集。对于德语键盘,Z和Y被交换了,每次我尝试使用C-y复制时都会隐藏我的窗口。(我猜最简单的方法是将复制绑定到C-z和C-y,但如果Emacs能够看到键盘扫描码或当前布局,那就太好了。) - user1001991
2
不要使用global-set-key/lookup-key,而是将重新映射添加到“function-key-map”中。这应该解决您的Help问题(除了Emacs只会告诉您关于“C-x b”,而不是“C-x и”),并且将自动处理任何绑定深度。 - Stefan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接