如何在不更改TAB的情况下将命令绑定到C-i?

时间:2009-11-24 19:21:34

标签: emacs

在emacs中,我想将命令绑定到C-i。所以我把(global-set-key "\C-i" 'forward-word)

在我的.emacs文件中。这是有效的,除了现在TAB键也被绑定到'前向词。

如何在不更改TAB的情况下将命令绑定到C-i?

6 个答案:

答案 0 :(得分:31)

简而言之,这应该为您解决问题:

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

更长的版本:

来自function keys上的emacs lisp文档:

  

在ASCII,C-i和< TAB>中。是相同的   字符。如果终端可以   区分它们,Emacs   传达了对Lisp的区别   通过将前者表示为的程序   整数9,后者为   符号标签。

     

大多数时候,它没用   区分这两者。通常情况下   local-function-key-map(见   翻译键映射)设置为映射   tab into 9.因此,一个键绑定   字符代码9(字符C-i)   也适用于标签。同样的   该组中的其他符号。该   函数read-char同样转换   这些事件变成了人物。

因此,一旦执行以下操作,您就可以看到键绑定的不同之处:

(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>")))

注意,每种模式都以不同的方式设置各种 TAB 绑定,因此您可能需要根据自己的需要对每种模式进行自定义。

版本依赖

以上适用于Emacs 23.1。来自新闻档案:

  

现在使用`local-function-key-map'映射功能键序列,   一个新变量。这继承自全局变量function-key-map,   不再直接使用。

这意味着,在版本22及更早版本中,您可以使用变量function-key-map获得相同的效果。我对此进行了测试,发现它与Emacs 21一起使用。

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

答案 1 :(得分:26)

我发现这个解决方案经过多次痛苦后,在邮件档案中丢失了。这很简单,避免与其他模式发生冲突,并且是唯一适用于我的模式:

;; 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)

答案 2 :(得分:14)

我建议如下:

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

至少应该从Emacs 23开始。

这类似于Caio的答案中的键盘翻译技术, 但运作水平略高。

键盘翻译的缺点是它甚至会生效 当Emacs没有运行读键序列时,特别是C-q C-i 将不再作为插入文字制表符的方式。

修改local-function-key-map不能正常工作,因为通常情况下 您希望<tab>键继续执行当前模式所具有的任何操作 为TAB定义。

答案 3 :(得分:1)

这个解决方案是前两个方案的组合,对我有用。在这种特殊情况下,我想将C-i重新分配给前一行。该解决方案保留了迷你缓冲区中TAB的功能。请注意,对于您使用钩子的模式,需要在本地细化TAB:

;  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)

答案 4 :(得分:1)

也许这可能有所帮助,因为它确实帮助了我:

而不是:

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

尝试:

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

答案 5 :(得分:1)

在看到这个问题之前,我提出了自己的解决方案:

(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])

这个工作的原因是,字母键生成的键码是[左侧]的“真实”键码,而tab,enter,escape generate键码是功能键符号。功能键符号已经在input-decode-map中映射到字母自然生成的相同符号,并将继续有效。

我将它们映射到的密钥代码使用与C-0等密钥代码相同的机制[即没有ASCII控制代码的密钥]。所以,它们被描述为例如C-i(因为它们被排除在将它们描述为TAB /等的特殊外壳之外),并且仍然具有事件修饰符/事件基本类型(控制)/?i。

缺点是它们有点难以使用 - 你必须使用数字,因为它们不会被(kbd)生成而你无法在向量文字中调用函数或变量。如果将C-i或C-m绑定到移动函数,它将适用于移位选择(因为即使它们是“假”键,模式仍然知道C-S-m被移位并且它的正常等效值是C-m)

注意:这会影响文本终端,因此如果您使用文本终端,则需要检测gui是否与(when window-system ...)一起运行 - 如果您将Emacs守护程序与图形窗口一起使用,您可能需要将其放入一个窗口设置挂钩。