Bingkai GUI
Dalam frame GUI (apakah X11, Windows, OSX, ...), Emacs membaca Tabkunci sebagai tombol tab
fungsi. Namun, karena Tabkunci pada terminal secara tradisional mengirimkan karakter ^I
( Control + I), Emacs menerjemahkan tab
kunci fungsi ke dalam karakter Control + I (karakter 9), yang ditampilkan sebagai TAB
. Terjemahan ini dilakukan melalui function-key-map
.
Terjemahan serupa terjadi dengan beberapa tombol fungsi lainnya. ( Backspacedan Deletemerupakan kasus pelik yang tidak akan saya bahas secara rinci di sini.)
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+[
Jika Anda ingin memisahkan Tabdari Ctrl+ Isama sekali, hapus ikatan dari function-key-map
:
(define-key function-key-map [tab] nil)
Namun hal ini tidak terlalu berguna, karena entri dalam function-key-map
ditimpa oleh binding di keymap modus-tertentu atau dalam peta global. Jadi, jika Anda ingin mendefinisikan pengikatan yang berbeda untuk tab
, lakukan saja (di Elisp, tidak secara interaktif, karena prompt membaca kunci menerapkan function-key-map
terjemahan sehingga Anda akhirnya akan memutuskan untuk membatalkan TAB
dan tidak tab
):
(global-set-key [tab] '…)
(define-key some-mode-map [tab] '…)
Semua mode standar yang memodifikasi aksi Tabkunci melakukannya dengan memodifikasi TAB
kunci, yang merupakan nama panggilan untuk C-i
karakter yang dihasilkan oleh kombinasi tombol Ctrl+ I. Jika Anda ingin binding standar untuk diterapkan tab
daripada C-i
, biarkan function-key-map
dan mode keymaps saja, dan alih-alih mengarahkan Ctrl+ Ike kunci yang berbeda.
(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] '…)
Sekarang Emacs akan melaporkan Ctrl+ Isebagai “ <control-i>
(diterjemahkan dari TAB
)”. Ini tidak cantik, tetapi tidak dapat dihindari: pencetakan karakter 9 yang cantik TAB
dimasukkan ke dalam kode sumber Emacs.
Bingkai terminal
Dalam bingkai terminal, masalahnya lebih sulit dan seringkali tidak mungkin. Terminal tidak mengirimkan kunci, mereka mengirimkan karakter (lebih tepatnya, mereka mengirimkan byte). The Tabkey ditransmisikan sebagai karakter tab - yang merupakan Control + I, sama seperti apa kombinasi tombol Ctrl+ Imenghasilkan. Tombol fungsi yang tidak memiliki karakter yang sesuai (seperti tombol kursor) ditransmisikan sebagai urutan melarikan diri, yaitu urutan karakter dimulai dengan ESC
= Control + [(itulah sebabnya Emacs mendefinisikan escapesebagai kunci awalan - ESC
harus menjadi awalan). Lihat Bagaimana cara kerja input keyboard dan output teks? untuk latar belakang lebih lanjut.
Ada beberapa terminal yang dapat dikonfigurasi untuk mengirim urutan tombol yang berbeda untuk tombol fungsi, tetapi tidak banyak. Kedua LeoNerd ini libtermkey / libtickit dan xterm Thomas Dickey ini (sejak versi 216) mendukung ini. Di Xterm, fitur ini opsional dan diaktifkan melalui modifyOtherKeys
sumber daya. Namun, saya tidak tahu adanya emulator terminal populer selain xterm yang mendukung ini, khususnya banyak emulator yang dibangun di atas libvte . Beberapa emulator terminal memungkinkan Anda melakukan ini secara manual melalui korespondensi yang ditentukan pengguna dari gantungan kunci untuk menghindari urutan.
Mekanisme ini memungkinkan banyak kombinasi tombol untuk dibedakan, bukan hanya tab / Ci, return / Cm dan escape / C- [. Lihat Masalah dengan ikatan kunci saat menggunakan terminal untuk deskripsi yang lebih rinci.
Fitur xterm dasar didukung sejak Emacs 24.4. Namun dasar-dasar (khususnya Tab, Return, Escape, Backspace) masih mengirim karakter kontrol tradisional, karena ini aplikasi apa harapkan. Ada mode di mana Ctrl+ lettermengirim urutan pelarian alih-alih karakter kontrol. Jadi untuk membedakan tombol fungsi dari Ctrlkombinasi pada Emacs 24.4, modifikasi dukungannya untuk modifyOtherKeys
menggunakan mode ini dengan mengatur sumber daya ke 2 alih-alih 1.
;; 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))