Các vấn đề với keybindings khi sử dụng thiết bị đầu cuối


30

Tôi có dòng sau init.el:

(global-set-key [(control \;)] 'comment-region)

Nó hoạt động rất tốt trong cửa sổ GUI, nhưng nếu emacsđược gọi với -nwtùy chọn thì C-;không nhận xét vùng, chỉ chèn ;ký tự. M-x comment-region REThoạt động tốt tuy nhiên.

Tôi đã cố gắng làm theo câu trả lời này về vấn đề tương tự, nhưng C-q C-;chỉ trả về ;và rõ ràng tôi không muốn ràng buộc trần ;.

Làm thế nào để đạt được hiệu quả mong muốn?


4
Có thể là thiết bị đầu cuối của bạn (nhân tiện, bạn đang sử dụng cái gì?) Không nhận ra chuỗi lệnh đó. Hãy thử sử dụng C-;kết hợp và sau đó sử dụng M-x view-lossageđể xem liệu nó có đến Emacs hay không.
Dan

Tôi đang sử dụng gnome-terminalM-x view-lossagetrả lại:ESC [ > 1 ; 2 8 0 2 ; 0 c ; ESC x v i e w - l o s s a g e RET
WeSenseASoulInSearchOfAnswers

3
Trông giống như một vấn đề thiết bị đầu cuối: nếu đó là tổ hợp phím để đạt Emacs, nó sẽ trông như thế C-;chứ không phải c ;(hoặc, ít nhất, tôi nhận được C-;).
Dân

@Dan: Bạn có thể đưa ra câu trả lời không? Điều đó sẽ đánh dấu câu hỏi như đã trả lời và giúp dễ dàng nhìn thấy giải pháp hơn, điều này tốt cho những người khác có cùng vấn đề. Cảm ơn!
Tikhon Jelvis

Tóm tắt và đăng với một liên kết bổ sung để đọc thêm. Cũng chỉnh sửa tiêu đề câu hỏi để làm cho nó chung chung hơn một chút.
Dan

Câu trả lời:


17

Đầu tiên, vấn đề chung hơn: trình giả lập thiết bị đầu cuối thường bị giới hạn trong các chuỗi điều khiển và thoát mà chúng có thể gửi. Vì vậy: đó có thể là trường hợp thiết bị đầu cuối nuốt các ký tự đặc biệt của bạn trước khi chúng tiếp cận Emacs. Là một chẩn đoán chung, bạn có thể nhấn C-h l(hoặc M-x view-lossage) để xem liệu các tổ hợp phím của bạn có biến nó thành Emacs hay không.

Để thảo luận thêm về vấn đề này, hãy xem chủ đề Stack Overflow này và các liên kết trong đó.

Để tóm tắt qua lại trong các bình luận, vấn đề cụ thể của bạn cho thấy đó là thiết bị đầu cuối chứ không phải là Emacs là vấn đề. Khi bạn đã cố gắng C-;và sau đó M-x view-lossage, bạn đã nhận được blah blah blah c ; ESC v i e w - l o s s a g e RET. Trông giống như một vấn đề cuối cùng: nếu tổ hợp phím đang chạm tới Emacs, c ;phần đó sẽ trông như thế C-;.


33

Trong Shift + Up không được Emacs nhận ra trong một thiết bị đầu cuối, tôi giải thích cách các thiết bị đầu cuối chuyển hầu hết các phím chức năng thành các chuỗi thoát, bởi vì giao diện giữa các ứng dụng và thiết bị đầu cuối truyền các ký tự (hay đúng hơn là byte), chứ không phải các khóa. Chỉ có một vài kết hợp sửa đổi + ký tự có ký tự riêng của chúng:

  • Ctrlcộng với một chữ cái hoặc một trong số các @[\]^_biến thành byte 0 Biệt31 (ký tự điều khiển ASCII ).
  • Thường thì Ctrl+ ?biến thành byte 127 và Ctrl+ Spacetương đương với Ctrl+ @(byte 0).
  • Một số phím chức năng tương đương với các ký tự điều khiển: Tab= Ctrl+ I, Return= Ctrl+ M, Esc= Ctrl+ [.
  • Backspace= Ctrl+ Hhoặc Ctrl+ ?tùy thuộc vào cấu hình. Ctrl+ ?thuận tiện hơn cho Emacs, vì Ctrl+ Hlà trợ giúp.
  • Meta+ characterđược gửi Esctheo sau bởi ký tự .

Vậy những kết hợp khác như Ctrl+ ;hoặc Ctrl+ Shift+ letterthì sao? Vì không có ký tự tương ứng, thiết bị đầu cuối phải sử dụng lại một ký tự hoặc gửi một chuỗi thoát. Nhiều thiết bị đầu cuối bỏ qua các sửa đổi khi không có ký tự tương ứng, vì vậy bạn kết thúc bằng Ctrl+ ;gửi ;, Ctrl+ Shift+ lettertương đương với Ctrl+ letter, v.v.

Các nhà cung cấp thiết bị đầu cuối tiếp tục làm điều đơn giản trong một thời gian dài. Không có tiêu chuẩn nào cho các chuỗi thoát, đó là tự tồn tại - các nhà cung cấp thiết bị đầu cuối không thực hiện nó, các ứng dụng không hỗ trợ nó, người dùng không mong đợi nó. Một số trình giả lập thiết bị đầu cuối có thể được cấu hình để gửi các chuỗi thoát tùy ý, vì vậy nếu bạn có thể, bạn có thể định cấu hình nó và khai báo các chuỗi thoát cho Emacs (sẽ nói thêm về điều này sau).

Gần đây, tình hình đang thay đổi, vì đã có hai đề xuất để chuẩn hóa các chuỗi thoát. Một là libtermkey của LeoNerd với cú pháp . Một cái khác là xterm của Thomas Dickey với cú pháp . Các phiên bản hiện tại của xterm (≥216) có thể được cấu hình cho một trong hai cú pháp bằng cách đặt tài nguyên; tính năng phải được kích hoạt bằng cách đặt giá trị khác không.ESC [ codepoint ; modifier uESC [ 2 7 ; modifier ; codepoint ~formatOtherKeysmodifyOtherKeys

Nếu trình giả lập thiết bị đầu cuối của bạn không hỗ trợ các cú pháp này nhưng có thể được định cấu hình, hãy chọn một trong hai.

Kể từ Emacs 24.4, Emacs tự động bật modifyOtherKeystính năng khi phát hiện thiết bị đầu cuối là phiên bản xterm ≥216. Phát hiện các chuỗi thoát của Emacs để mã hóa khóa hoạt động thông qua biến local-function-key-map. Kể từ Emacs 24.4, không phải tất cả các chuỗi thoát đều được hỗ trợ. Bạn có thể sử dụng đoạn mã sau trong tệp init của mình để hoàn thành công việc.

;; xterm with the resource ?.VT100.modifyOtherKeys: 1
;; 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))
    (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;3u" meta)
                ("\e\[%d;5u" control)
                ("\e\[%d;6u" control shift)
                ("\e\[%d;7u" control meta)
                ("\e\[%d;8u" control meta shift)))
        (setq c (1+ c))))))
(eval-after-load "xterm" '(my-eval-after-load-xterm))

Nếu TERMbiến môi trường không được đặt thành xtermhoặc một biến thể như xterm-256color, Emacs sẽ không kích hoạt các chuỗi đó. Nếu Emacs đã hỗ trợ cho giá trị của TERMbạn, bạn có thể thêm hỗ trợ bằng cách xác định hàm tương tự như hàm trên, để được thực thi sau khi tải tệp Lisp có tên là giá trị củaTERM . Nếu Emacs không có sự ủng hộ như vậy, bạn có thể thêm nó bằng cách tạo ra một thư mục con gọi là termđâu đó trong bạn load-path, và tạo ra một tập tin gọi là Lisp term/$TERM.elnơi $TERMlà giá trị của TERMđịnh một hàm gọi terminal-init-$TERM.

Khi tôi viết, có vẻ như rất ít trình giả lập thiết bị đầu cuối khác ngoài xterm đã áp dụng các chuỗi thoát này. Trên OSX, bạn có thể định cấu hình iTerm2 bằng cách chọn một chuỗi thoát cho từng tổ hợp phím, từng cái một.


2
Câu trả lời của bạn về chủ đề này luôn luôn tuyệt vời, Gilles. Nhiều đánh giá cao.
phils

Tuyệt quá!. Mặc dù tôi có khá nhiều thời gian để tìm cách làm cho urxvt gửi những chuỗi đó. Bạn có thể giúp tôi một tay được không :)
Amos

@Amos Tôi không sử dụng rxvt. Bạn nên hỏi trên Unix & Linux cách làm cho urxvt gửi các chuỗi thoát tương tự như xterm với redirectOtherKeys.
Gilles 'SO- ngừng trở nên xấu xa'

không hoạt động trên macOS xterm-256color. M-C-%được công nhậnESC 5
LoranceChen

@LoranceChen Đó là hành vi dự kiến ​​nếu modifyOtherKeystính năng này không hoạt động. Lưu ý rằng nó chỉ được hỗ trợ trong các phiên bản xterm đủ gần đây và nó chỉ được kích hoạt tự động kể từ Emacs 24.4. Tôi không biết nếu OSX xuất xưởng với các phiên bản gần đây. Nếu không, và nó không hiệu quả với bạn, tôi khuyên bạn nên hỏi một câu hỏi mới. Đề cập đến các phiên bản mà bạn đang sử dụng.
Gilles 'SO- ngừng trở nên xấu xa'

2

Câu trả lời của Gilles đã nêu: On OSX, you can configure iTerm2 by selecting an escape sequence for each key combination, one by one. Tôi gặp một chút rắc rối khi đến đó, vì vậy đây là một lời giải thích chi tiết trong trường hợp bạn giống như tôi, bối rối.

Nếu, khi chạy Emacs trong một thiết bị đầu cuối (ví dụ, Terminal.app mặc định của Mac) C-x C-;không chạy comment-linevà bạn muốn chức năng đó, thì bạn phải chuyển sang iTerm2 (Terminal.app không có khả năng) và tạo Ánh xạ khóa trong Hồ sơ ... Các phím như sau:

^;     ^[[59;5u

Điều này được thực hiện bằng cách nhấp vào +nút, sẽ hiển thị một cửa sổ nhỏ gọi là "Phím tắt bàn phím"; cửa sổ này ban đầu có hai trường; trên cùng có giá trị "Nhấp để đặt" và phía dưới có giá trị "Bỏ qua". Nhấp vào nút trên cùng và gõ C-;. Cái này đặt tổ hợp phím sẽ chạy hành động và mã. Nhấp vào trường dưới cùng, "Hành động", và tìm và nhấp vào "Gửi chuỗi thoát", cách đó hơn một nửa. Sau khi bạn nhấp vào đó, một trường thứ ba sẽ xuất hiện, được gọi là "Esc +". Trong trường này, gõ:

[59;5u

Các 59là mã thập phân ASCII dấu phẩy, và là 5là mã cho Ctrl. Sau đó nhấn "OK" để hoàn tất. Bây giờ, tổ hợp phím chính xác cho chuỗi khóa sẽ được bao gồm trong tùy chọn của iTerm2. Khi bạn khởi động Emacs trong iTerm, bây giờ bạn sẽ có quyền truy cập vào C-x C-;chức năng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.