2009-11-24 33 views
26

Trong emacs, tôi muốn ràng buộc một lệnh để C-i. Vì vậy, tôi đặt (global-set-key "\C-i" 'forward-word)Làm cách nào để liên kết lệnh với C-i mà không thay đổi TAB?

trong tệp .emacs của tôi. Điều này hoạt động, ngoại trừ bây giờ khóa TAB được ràng buộc để 'chuyển tiếp từ là tốt.

Làm cách nào để liên kết lệnh với C-i mà không thay đổi TAB?

Trả lời

29

Nói tóm lại, điều này sẽ giải quyết vấn đề cho bạn:

(setq local-function-key-map (delq '(kp-tab . [9]) local-function-key-map)) 
(global-set-key (kbd "C-i") 'forward-word) 

dài hơn phiên bản:

Từ Emacs Lisp tài liệu về function keys:

Trong ASCII, Ci và < TAB> giống với ký tự . Nếu thiết bị đầu cuối có thể phân biệt giữa chúng, Emacs truyền tải sự khác biệt cho các chương trình Lisp bằng cách trình bày trước đây là số nguyên 9 và sau đó là tab biểu tượng .

Hầu hết thời gian, không hữu ích khi phân biệt hai. Vì vậy, thông thường local-function-key-map (xem Bản dịch Keymaps) được thiết lập để ánh xạ tab thành 9. Do đó, một ràng buộc khóa cho mã ký tự 9 (ký tự C-i) cũng áp dụng cho tab. Tương tự như vậy đối với các ký hiệu khác trong nhóm này, . Chức năng đọc cũng tương tự như vậy chuyển đổi các sự kiện này thành các ký tự .

Vì vậy, một khi bạn làm những điều sau đây, bạn có thể thấy sự khác biệt trong tổ hợp phím:

(setq local-function-key-map (delq '(kp-tab . [9]) local-function-key-map)) 

;; this is C-i 
(global-set-key (kbd "C-i") (lambda() (interactive) (message "C-i"))) 
;; this is <tab> key 
(global-set-key (kbd "<tab>") (lambda() (interactive) (message "<tab>"))) 

Lưu ý, mỗi chế độ thiết lập các hình TAB bindings khác nhau, vì vậy bạn có thể cần phải làm tùy chỉnh cho mỗi chế độ mà bạn quan tâm.

Version phụ thuộc:

Các công trình trên cho Emacs 23,1. Từ tệp tin TIN TỨC:

Các chuỗi phím chức năng hiện được ánh xạ bằng cách sử dụng biến địa phương 'chức năng-bản đồ', . Điều này kế thừa từ chức năng biến toàn cầu-key-map, mà không được sử dụng trực tiếp nữa.

Có nghĩa là, trong các phiên bản 22 trở lên, bạn có thể nhận được hiệu ứng tương tự bằng cách sử dụng biến function-key-map. Tôi đã thử nghiệm điều này và thấy nó hoạt động với Emacs 21.

(setq local-function-key-map (delq '(kp-tab . [9]) function-key-map)) 
(global-set-key (kbd "C-i") 'forward-word) 
+0

Khi tôi thử mã này, tôi gặp lỗi khi địa phương-chức năng-key-map bị vô hiệu. Bất kỳ suy nghĩ về lý do tại sao nó sẽ bị vô hiệu? – Steve

+0

@Steve Biến được định nghĩa trong Emacs 23, tôi đã cập nhật câu trả lời với phiên bản 22 và cũ hơn. –

+3

Điều này đã không chính xác làm việc cho tôi. Không có bất kỳ thay đổi nào, khóa 'tab' đã bị bỏ cấm. Tôi đã thử thực hiện "khóa toàn cầu" thứ 2 cho , một phần đã giải quyết được vấn đề, nhưng ngăn tab hoàn thành trong minibuffer. Sử dụng giải pháp của Caio dưới đây dường như làm các trick. – mksuth

23

Tôi tìm thấy giải pháp này, sau nhiều nỗi đau, mất trong kho lưu trữ thư.Rất đơn giản, tránh xung đột với các chế độ khác và chỉ là xung đột với các chế độ khác và là đối tác duy nhất hiệu quả với tôi:

;; Translate the problematic keys to the function key Hyper: 
(keyboard-translate ?\C-i ?\H-i) 
(keyboard-translate ?\C-m ?\H-m) 
;; Rebind then accordantly: 
(global-set-key [?\H-m] 'delete-backward-char) 
(global-set-key [?\H-i] 'iswitchb-buffer) 
1

Giải pháp này là sự kết hợp của hai nhóm trước đó, đã hiệu quả đối với tôi. Trong trường hợp cụ thể này, tôi muốn giao lại C-i cho dòng trước. Giải pháp này bảo tồn chức năng của TAB trong minibuffer. Lưu ý TAB mà cần phải được tinh chế tại địa phương cho các phương thức bạn sử dụng với một cái móc:

; As mentioned in the other solution, C-i and TAB are the same character in ASCII. 
; We have to differentiate between the two and reassign each in a roundabout way. 

; differentiate tab from C-i 
(setq local-function-key-map (delq '(kp-tab . [9]) function-key-map)) 

;; Translate the problematic key to the function key Hyper: 
(keyboard-translate ?\C-i ?\H-i) 

;; Rebind accordingly 
(global-set-key [?\H-i] 'previous-line) 

; Finish by redefining tab for c-mode. 
(defun my-c-mode-common-hook() 
(local-set-key (kbd "<tab>") 'indent-for-tab-command) 
    ) 

(add-hook 'c-mode-common-hook 'my-c-mode-common-hook) 
+0

Không có phương pháp nào được mô tả trong chuỗi này phù hợp với tôi. C-i vẫn bị ràng buộc vào tab. Bất kỳ ý tưởng tại sao? – user69818

12

Tôi khuyên bạn nên điều sau đây:

(define-key input-decode-map (kbd "C-i") (kbd "H-i")) 
(global-set-key (kbd "H-i") 'whatever-you-want) 

Nó sẽ làm việc từ ít nhất Emacs 23.

này tương tự như kỹ thuật dịch bàn phím trong câu trả lời của Caio, nhưng hoạt động ở mức cao hơn một chút.

Những bất lợi của bàn phím-dịch là nó sẽ có hiệu lực ngay cả khi khi Emacs không chạy đọc-key-chuỗi, và đặc biệt C-q C-i sẽ không còn làm việc như là một cách để chèn một ký tự tab chữ.

Sửa đổi cục bộ chức năng-key-map không hoạt động tốt, vì thường bạn muốn phím <tab> tiếp tục làm bất cứ điều gì các chế độ hiện hành đã định nghĩa cho TAB.

+0

Điều này làm việc cho tôi khi tôi muốn khôi phục lại C-i. Tôi không thể có được phương pháp được đề xuất trong câu trả lời được chấp nhận làm việc chính xác, nhưng theo cách này đã nhận được nó. – nonex

1

Có lẽ điều này có thể giúp đỡ, vì nó đã giúp tôi:

Thay vì:

; differentiate tab from C-i (setq local-function-key-map (delq '(kp-tab . [9]) function-key-map))

Hãy thử:

(define-key local-function-key-map [tab] nil)

+0

Tác phẩm này dành cho tôi tại Emacs 24. – tom

0

tôi đã đưa ra giải pháp của riêng tôi trước nhìn thấy câu hỏi này:

(define-key input-decode-map [#x2000009] [#x6000069]) ; C-S-i 
(define-key input-decode-map [#x200000d] [#x600006d]) ; C-S-m 
(define-key input-decode-map "\C-i" [#x4000069]) 
(define-key input-decode-map "\C-m" [#x400006d]) 
(define-key input-decode-map "\C-[" [#x400005b]) 

Lý do hoạt động này là, mã khóa mà phím chữ tạo ra là mã khóa "thực" ở bên trái, trong khi mã khóa mà tab, nhập, thoát tạo ra là các ký hiệu phím chức năng. Các ký hiệu phím chức năng đã được ánh xạ trong bản đồ giải mã đầu vào đến cùng một ký hiệu mà các chữ tự nhiên tạo ra và sẽ tiếp tục hoạt động.

Các mã khóa mà tôi đã ánh xạ chúng đến sử dụng cùng một cơ chế như mã khóa cho C-0, v.v. các khóa không có mã kiểm soát trong ASCII]. Vì vậy, chúng được mô tả là ví dụ: C-i (vì chúng bị loại trừ khỏi vỏ đặc biệt mô tả chúng là TAB/etc), và vẫn có biến tố sự kiện/event-basic-type (control) /? I.

Nhược điểm là chúng khó làm việc hơn - bạn phải sử dụng các số, vì chúng sẽ không được tạo bởi kbd và bạn không thể gọi hàm hoặc biến trong vector vectơ . Nếu bạn liên kết Ci hoặc Cm với chức năng chuyển động, nó sẽ hoạt động với lựa chọn dịch chuyển (vì mặc dù chúng là khóa "giả", chế độ vẫn biết rằng CSm được dịch chuyển và nó tương đương bình thường là Cm)

LƯU Ý: Điều này sẽ tác động đến các thiết bị đầu cuối văn bản, vì vậy nếu bạn sử dụng các thiết bị đầu cuối văn bản, bạn sẽ cần phải phát hiện xem gui có đang chạy với (when window-system ...) hay không - nếu bạn sử dụng Emacs Daemon với các cửa sổ đồ họa, bạn có thể đặt nó vào một cửa sổ cài đặt.

Các vấn đề liên quan