GUIフレーム
GUIフレーム(X11、Windows、OSXなど)では、EmacsはTabキーをtab
ファンクションキーとして読み取ります。ただし、Tab端末のキーは伝統的に^I
(Control + I)文字を送信するため、Emacsはtab
ファンクションキーをControl + I文字(文字9)に変換しますTAB
。この変換はを介して行われfunction-key-map
ます。
他のいくつかのファンクションキーでも同様の変換が行われます。(BackspaceそしてDelete、私はここで詳細に議論しない厄介なケースです。)
Function key Translated to character Notes
Number Name Decomposition
backspace 127 DEL Ctrl+? May be translated to C-h instead
tab 9 TAB Ctrl+I
linefeed 10 LFD Ctrl+J Few keyboards have this key
return 13 RET Ctrl+M
escape 27 ESC Ctrl+[
+ から完全に分離Tabしたい場合は、次からバインディングを削除します。CtrlIfunction-key-map
(define-key function-key-map [tab] nil)
ただし、のエントリfunction-key-map
はモード固有のキーマップまたはグローバルマップのバインディングによってオーバーライドされるため、これはあまり役に立ちません。あなたは異なるが、バインディング定義したいのであればtab
、ちょうどそれを行う(elispのではなく、対話形式で、プロンプト読んキーが適用されるためfunction-key-map
、あなたが再バインド終わると思いますので、翻訳をTAB
していませんtab
)。
(global-set-key [tab] '…)
(define-key some-mode-map [tab] '…)
Tabキーのアクションを変更するすべての標準モードは、キーを変更することで実行しTAB
ます。これはC-i
、キーの組み合わせCtrl+ によって生成される文字のニックネームですI。にtab
ではなく標準のバインディングを適用する場合はC-i
、キーfunction-key-map
マップをそのままにしてモードを解除し、代わりにCtrl+ Iを別のキーにリダイレクトします。
(define-key input-decode-map [(control ?i)] [control-i])
(define-key input-decode-map [(control ?I)] [(shift control-i)])
(define-key some-mode-map [control-i] '…)
これで、EmacsはCtrl+ Iを「<control-i>
(から翻訳TAB
)」として報告します。これはきれいではありませんが、避けられませんTAB
。Emacsソースコードに組み込まれている文字9のきれいな印刷です。
端子台
ターミナルフレームでは、問題はより難しく、多くの場合不可能です。端末はキーを送信せず、文字を送信します(実際には、バイトを送信します)。Tabコントロール+ Iで、キーの組み合わせ何と同じ-キーはタブ文字として送信されてCtrl+がI生成されます。対応する文字を持たないファンクションキー(カーソルキーなど)は、エスケープシーケンスとして送信されます。つまり、ESC
= Control + [で始まる文字のシーケンスです(これが、Emacs escapeがプレフィックスキーとして定義する理由—プレフィックスであるESC
必要があります)。キーボード入力とテキスト出力の仕組みをご覧ください。より多くの背景。
ファンクションキーに異なるキーシーケンスを送信するように構成できる端末はいくつかありますが、多くはありません。LeoNerdのlibtermkey / libtickitとThomas Dickeyのxterm(バージョン216以降)の両方がこれをサポートしています。Xtermでは、この機能はオプションであり、modifyOtherKeys
リソースを介してアクティブ化されます。ただし、これをサポートするxterm以外の一般的な端末エミュレーター、特にlibvteで構築された多くのエミュレーターは知りません。一部のターミナルエミュレータでは、キーコードからエスケープシーケンスへのユーザー定義の対応を通じて、これを手動で行うことができます。
このメカニズムにより、タブ/ Ci、return / Cm、およびescape / C- [だけでなく、多くのキーの組み合わせを区別できます。より詳細な説明については、ターミナル使用時のキーバインディングの問題を参照してください。
Emacs 24.4以降、基本的なxterm機能がサポートされています。しかし、ファンダメンタルズ(特にはTab、Return、Escape、Backspaceそれはアプリケーションが期待するものだから)まだ、従来の制御文字を送信します。Ctrl+ letterが制御文字の代わりにエスケープシーケンスを送信するモードがあります。そのため、ファンクションキーCtrlとEmacs 24.4 の組み合わせを区別するにはmodifyOtherKeys
、リソースを1ではなく2に設定して、このモードを使用するためのサポートを変更します。
;; xterm with the resource ?.VT100.modifyOtherKeys: 2
;; GNU Emacs >=24.4 sets xterm in this mode and define
;; some of the escape sequences but not all of them.
(defun character-apply-modifiers (c &rest modifiers)
"Apply modifiers to the character C.
MODIFIERS must be a list of symbols amongst (meta control shift).
Return an event vector."
(if (memq 'control modifiers) (setq c (if (or (and (<= ?@ c) (<= c ?_))
(and (<= ?a c) (<= c ?z)))
(logand c ?\x1f)
(logior (lsh 1 26) c))))
(if (memq 'meta modifiers) (setq c (logior (lsh 1 27) c)))
(if (memq 'shift modifiers) (setq c (logior (lsh 1 25) c)))
(vector c))
(defun my-eval-after-load-xterm ()
(when (and (boundp 'xterm-extra-capabilities) (boundp 'xterm-function-map))
;; Override the standard definition to set modifyOtherKeys to 2 instead of 1
(defun xterm-turn-on-modify-other-keys ()
"Turn the modifyOtherKeys feature of xterm back on."
(let ((terminal (frame-terminal)))
(when (and (terminal-live-p terminal)
(memq terminal xterm-modify-other-keys-terminal-list))
(send-string-to-terminal "\e[>4;2m" terminal))))
(let ((c 32))
(while (<= c 126)
(mapc (lambda (x)
(define-key xterm-function-map (format (car x) c)
(apply 'character-apply-modifiers c (cdr x))))
'(;; with ?.VT100.formatOtherKeys: 0
("\e\[27;3;%d~" meta)
("\e\[27;5;%d~" control)
("\e\[27;6;%d~" control shift)
("\e\[27;7;%d~" control meta)
("\e\[27;8;%d~" control meta shift)
;; with ?.VT100.formatOtherKeys: 1
("\e\[%d;3~" meta)
("\e\[%d;5~" control)
("\e\[%d;6~" control shift)
("\e\[%d;7~" control meta)
("\e\[%d;8~" control meta shift)))
(setq c (1+ c)))))
(define-key xterm-function-map "")
t)
(eval-after-load "xterm" '(my-eval-after-load-xterm))