Emacs:键绑定到TAB会破坏迷你缓冲区中的自动完成功能

时间:2014-03-20 02:40:56

标签: emacs autocomplete elisp minibuffer

简单地说,我只是在TAB键上设置了一个键绑定,但是现在当我在迷你缓冲区中按TAB来自动完成命令时,它会失败并显示以下消息:The mark is not set now, so there is no region

换句话说,当我的光标位于缓冲区(而不是迷你缓冲区)时,我只需要我的TAB键绑定。

在下面的示例中,当我在缓冲区中处于文本/基本模式时,如何在迷你缓冲区中丢失自动完成时如何将我的选项卡设置为缩进?我有以下功能和键绑定:

;; Shift the selected region right if distance is postive, left if
;; negative

 (defun shift-region (distance)
   (let ((mark (mark)))
     (save-excursion
       (indent-rigidly (region-beginning) (region-end) distance)
       (push-mark mark t t)
       ;; Tell the command loop not to deactivate the mark
       ;; for transient mark mode
       (setq deactivate-mark nil))))

(defun shift-right ()
  (interactive)
  (shift-region 2))

(defun shift-left ()
  (interactive)
  (shift-region -2))

;; Bind (shift-right) and (shift-left) function to your favorite keys. I use
;; the following so that Ctrl-Shift-Right Arrow moves selected text one 
;; column to the right, Ctrl-Shift-Left Arrow moves selected text one
;; column to the left:

;; (global-set-key [C-S-right] 'shift-right)
;; (global-set-key [C-S-left] 'shift-left)
(global-set-key [tab] 'shift-right)
(global-set-key [backtab] 'shift-left)

3 个答案:

答案 0 :(得分:4)

除了别人说的话:

  1. TAB密钥通常<tab>相同,这是您通过指定[tab]使用的密钥。 TAB密钥与C-i相同,您可以使用(kbd "TAB")绑定它。

  2. 如果您愿意,可以继续将TAB绑定到global-map中的命令,就像您所做的那样,但是通过重新绑定它来覆盖迷你缓冲区的命令每个迷你缓冲区键映射到你喜欢的任何命令。

    例如,如果您想要TAB的常用迷你缓冲区绑定,请执行以下操作:

    1. 使用emacs -Q启动Emacs(无初始文件)。

    2. 可选择加载任何对TAB进行非默认迷你缓冲区绑定的库(例如自动填充?)。

    3. 加载库help-fns+.el,获取全局绑定到describe-keymap的命令C-h M-k

    4. 使用C-h M-k检查您的Emacs版本所使用的每个迷你缓冲区键盘映射中TAB的绑定。 这将包括minibuffer-local-mapminibuffer-local-completion-mapminibuffer-local-must-match-map,还可能包含更多内容。有关迷你缓冲区键映射变量的列表,请参阅(elisp) Completion Commands

      例如,C-h M-k minibuffer-local-completion-map显示该键映射中的绑定。在列表中查找TAB

      (如果您不想下载help-fns+.el,那么您可以使用lookup-key。该库只会轻松列出键盘中的键。)

    5. TAB绑定到init文件中的默认绑定后,将其全局绑定到非面向迷你缓冲区的命令。 IOW,按原样恢复迷你缓冲区绑定。

答案 1 :(得分:4)

问题只是您将命令绑定到[tab]而不是"\t"tab表示GUI下的TAB键,但在tty Emacs下接收TAB字符(即?\t),因此当您点击tab时Emacs首先查找tab绑定,如果没有,function-key-map重新映射会将其转换为?\t并再次尝试。迷你缓冲区仅绑定"\t",因此任何与[tab]的全局绑定都将优先。

简而言之,请使用(global-set-key "\t" 'shift-right),这个问题就会消失。

答案 2 :(得分:2)

您可以使用window-minibuffer-p功能检查您是否在迷你缓冲区中。从文档

Return non-nil if WINDOW is a minibuffer window.
WINDOW must be a valid window and defaults to the selected one.

emacs 24.4已经提供了你想要在上面的功能中实现的东西。命令indent-rigidly已得到增强,您可以使用 left right tab shift-缩进区域选项卡键。

您可以选择要缩进的区域,然后按 Cx 选项卡,之后您可以使用右<区域将区域移动一个空格< / kbd>和键。您还可以使用选项卡 shift-tab 键将所选区域移动一个选项卡空间,这非常方便,因为上面的键绑定在您按任何其他键之前保持活动状态