เฟรม GUI
ในเฟรม GUI (ไม่ว่าจะเป็น X11, Windows, OSX, …), Emacs จะอ่านค่าTabเป็นtab
ปุ่มฟังก์ชั่น แต่เพราะTabที่สำคัญเกี่ยวกับขั้วประเพณีส่ง^I
( ควบคุม + I) ตัวอักษร Emacs แปลtab
ปุ่มฟังก์ชั่เข้าไปใน Control + ฉันตัวอักษร (ตัวอักษร 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จากCtrl+ Iทั้งหมดให้ลบการผูกออกจากfunction-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
)” สิ่งนี้ไม่สวย แต่ก็หลีกเลี่ยงไม่ได้: การพิมพ์ตัวอักษรสวย ๆ 9 ที่TAB
สร้างไว้ในซอร์สโค้ด Emacs
เฟรมเทอร์มินัล
ในเฟรมเทอร์มินัลปัญหานั้นยากและเป็นไปไม่ได้บ่อยครั้ง เทอร์มินัลไม่ส่งคีย์พวกเขาส่งอักขระ (ที่จริงแล้วพวกเขาส่งไบต์) Tabที่สำคัญจะถูกส่งเป็นตัวละครแท็บ - ซึ่งเป็น Control + I, เช่นเดียวกับสิ่งคีย์ผสมCtrl+ Iสร้าง ปุ่มฟังก์ชั่นที่ไม่มีตัวอักษรที่เกี่ยวข้อง (เช่นเคอร์เซอร์เคอร์เซอร์) จะถูกส่งเป็น escape sequences นั่นคือลำดับของตัวอักษรที่ขึ้นต้นด้วยESC
= Control + [(ซึ่งเป็นสาเหตุที่ Emacs กำหนดescapeเป็นคีย์คำนำหน้า - ESC
ต้องเป็นส่วนนำหน้า) ดูที่คีย์บอร์ดและเอาต์พุตข้อความทำงานอย่างไร สำหรับพื้นหลังเพิ่มเติม
มีเทอร์มินัลไม่กี่แห่งที่สามารถกำหนดค่าให้ส่งลำดับคีย์ที่แตกต่างกันสำหรับปุ่มฟังก์ชัน แต่ไม่มาก ทั้งLeoNerd's libtermkey / libtickitและxterm ของ Thomas Dickey (ตั้งแต่รุ่น 216) สนับสนุนสิ่งนี้ ใน Xterm คุณลักษณะนี้เป็นทางเลือกและเปิดใช้งานผ่านmodifyOtherKeys
ทรัพยากร แต่ผมไม่ทราบว่าของจำลอง terminal ใด ๆ ที่นิยมอื่น ๆ กว่า xterm ที่สนับสนุนการนี้โดยเฉพาะอย่างยิ่งในการเลียนแบบจำนวนมากที่สร้างขึ้นบนlibvte เทอร์มินัลอีมูเลเตอร์บางตัวช่วยให้คุณทำสิ่งนี้ได้ด้วยตนเองผ่านการโต้ตอบที่ผู้ใช้กำหนดเองจาก keychords เพื่อหลีกเลี่ยงลำดับ
กลไกนี้ช่วยให้สามารถแยกแยะคีย์ผสมต่าง ๆ ได้ไม่เพียงแค่ tab / Ci, return / Cm และ escape / C- [ ดูที่ปัญหาเกี่ยวกับการผูกกุญแจเมื่อใช้เทอร์มินัลสำหรับคำอธิบายโดยละเอียดเพิ่มเติม
รองรับคุณสมบัติ xterm พื้นฐานตั้งแต่ Emacs 24.4 อย่างไรก็ตามปัจจัยพื้นฐาน (โดยเฉพาะอย่างยิ่งTab, Return, Escape, Backspace) ยังคงส่งตัวควบคุมแบบดั้งเดิมเพราะที่สิ่งที่ใช้งานคาดหวัง มีโหมดที่Ctrl+ letterส่งลำดับ escape แทนอักขระควบคุม ดังนั้นเพื่อแยกความแตกต่างของปุ่มฟังก์ชั่นจากCtrlชุดค่าผสมบน Emacs 24.4 ให้ปรับเปลี่ยนการรองรับสำหรับmodifyOtherKeys
การใช้โหมดนี้โดยการตั้งค่าทรัพยากรเป็น 2 แทน 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))