【问题标题】:How do I bind C-= in emacs?如何在 emacs 中绑定 C-=?
【发布时间】:2012-05-26 11:11:54
【问题描述】:

我的.emacs 文件中的这个 s 表达式没有产生预期的结果:

(define-key global-map (kbd "C-=") 'djhaskin987-untab-to-tab-stop)

为什么我不能将命令绑定到 Ctrl+=

编辑澄清:

我在 Debian 的 urxvt-256colors 的标准版本上使用 emacs23-nox,除了我已经用 --disable-iso405776(或类似的东西)重新编译它以便 Ctrl+Shift 不会做奇怪的“插入字符”的事情。我不知道这是否会影响任何事情。比如C-M-i发送M-TAB,我看不懂。

编辑二

我很抱歉没有说清楚。函数djhaskin987-untab-to-tab-stop 中包含(interactive) 行。这部分有效。

【问题讨论】:

  • C-i 在emacs中一般翻译为TAB。所以如果C-M-i被翻译成M-TAB,我不会感到惊讶

标签: emacs key-bindings


【解决方案1】:

您可以使用默认 ascii 代码映射 C-=:^[[61;5u。然后您可以使用以下方法在 Emacs 中绑定它:

(global-set-key (kbd "C-=") 'djhaskin987-untab-to-tab-stop))

或者让use-package去做,例如:

(use-package expand-region
  :ensure t
  :bind (("C-=" . er/expand-region)))

我要感谢 Sam Brightman,感谢他出色的解决方案。这是一种非常干净,虽然笨拙的方法,适用于任何无法通过普通 ascii 代码发送的密钥。很长一段时间以来,我一直想让 C-TAB 在 iterm2 中工作。我可以通过删除 C-TAB/C-S-TAB 的内置首选项键并使用他的方法来做到这一点。使用以下内容,我可以 ssh 进入远程 Linux 机器并快速切换项目中的大量打开缓冲区,就像桌面编辑器一样。

(use-package nswbuff
  :defer 1
  :after (projectile)
  :commands (nswbuff-switch-to-previous-buffer
             nswbuff-switch-to-next-buffer)
  :config
  (progn
    (my/global-map-and-set-key "C-TAB" 'nswbuff-switch-to-previous-buffer)
    (my/global-map-and-set-key "C-S-TAB" 'nswbuff-switch-to-next-buffer))
  :init
  (setq nswbuff-display-intermediate-buffers t
        nswbuff-exclude-buffer-regexps '("^ "
                                         "^\*.*\*"
                                         "\*Treemacs.*\*"
                                         "^magit.*:.+")
        nswbuff-include-buffer-regexps '("^*Org Src")
        nswbuff-start-with-current-centered t
        nswbuff-buffer-list-function '(lambda ()
                                        (interactive)
                                        (if (projectile-project-p)
                                            (nswbuff-projectile-buffer-list)
                                          (buffer-list)))))

【讨论】:

    【解决方案2】:

    接受的答案与link in the first comment to it 相结合足以开始一个完整的解决方案。步骤是:

    1. 让您的终端输出密钥的转义码
    2. 让 Emacs 将转义码识别为标准按键
    3. 在模式映射中绑定按键

    第一个非常依赖终端和/或操作系统。

    第一条评论中的链接显示了 X Window System 的一些示例。键名在/usr/X11R6/include/X11/keysymdef.h 中可用(或尝试locate keysymdef.h),前缀为XK_(为了我们的目的应该删除)。我读到符号名称比键字面值更受欢迎。

    我目前没有运行 X,但我认为在你的情况下它应该是这样的:

    XTerm.VT100.Translations: #override \
    Ctrl ~Meta ~Shift  <Key> equal:         string(0x1b) string("[emacs-C-=")\n
    

    第一个字符串是转义符,第二个是你选择的。

    在 iTerm 中,您可以使用Preferences-&gt;Keys 并选择Send Escape Sequence 作为Action。例如,我有:

    Emacs Wiki lists some configuration methods 用于其他终端。

    现在您可以教 Emacs 将其识别为 C-=。首先将define-key 转换为input-decode-map。我有几个辅助函数:

    (defun my/global-map-and-set-key (key command &optional prefix suffix)
       "`my/map-key' KEY then `global-set-key' KEY with COMMAND.
     PREFIX or SUFFIX can wrap the key when passing to `global-set-key'."
       (my/map-key key)
       (global-set-key (kbd (concat prefix key suffix)) command))
    
     (defun my/map-key (key)
       "Map KEY from escape sequence \"\e[emacs-KEY\."
       (define-key function-key-map (concat "\e[emacs-" key) (kbd key)))
    

    那么:

    (my/global-map-and-set-key "C-=" 'some-function-to-bind-to)
    

    某些键(当前:()\|;'`"#.,)需要在字符串中转义,例如 C-\.

    【讨论】:

      【解决方案3】:

      在终端中,TAB 由与C-i 相同的字节序列表示。通常终端没有C-=的特殊字节序列,所以它只会发送一个=。 Emacs 对此无能为力。但是你可以教你的终端模拟器发送一些你选择的特殊字节序列(查看你的终端模拟器的文档),之后你可以教 Emacs 将它识别为 C-= kbd>(类似于(define-key input-decode-map "...thebytes..." [?\C-=]))。

      【讨论】:

      • 感谢 Stefan.. 这非常有用.. 例如..在这个包中,有人费了很大力气让 xterm 更好地与 emacs 一起工作。 dur.ac.uk/p.j.heslin/Software/Emacs/Download/xterm-extras.el(请参阅 .Xresource 文件的注释)
      • +1 感谢您帮助我解决问题。我可以看到这是要走的路。
      • 也许最好在实际解决方案中进行编辑 - 链接的文件是经过压缩的,链接很容易中断。 C-= 在终端中是特殊的吗?一般的策略似乎是将 X 键转换为未使用的终端转义序列,然后为这些和其他以前未定义的终端转义定义 emacs 键(然后将这些键绑定到函数)。
      • @SamBrightman:请注意,第一条评论中的链接使用key-translation-map,但应该使用input-decode-map。这可能是由于 input-decode-map 仅在 Emacs-23 中引入这一事实造成的,在此之前您能做的最好的事情就是使用 key-translation-mapfunction-key-map
      • @Stefan 在守护进程模式下,input-decode-map 对我来说实际上是崩溃的,而function-key-map 在这两种模式下都有效。我现在已经改回了我的答案,因为我不明白什么是破坏。
      【解决方案4】:

      问题是您在终端中使用 emacs。 终端不允许“C-=”。 在图形 emacs 中尝试您的功能,它将起作用。 您必须为终端找到另一个键绑定。

      【讨论】:

      • 我意识到这一点,但出于个人喜好的目的(这样我什至可以通过 SSH 访问 emacs,并且我所有的东西都在终端中),我想让 C-= 甚至工作在终端中。
      【解决方案5】:

      您要绑定的函数必须是交互式的。试试:

      (define-key global-map (kbd "C-=") 
          (lambda () (interactive) (djhaskin987-untab-to-tab-stop)))
      

      【讨论】:

      • 恐怕不是,但感谢您的提示。当我使用此行(或我的行)并按 CTRL+= 时,它只会向缓冲区写入一个“=”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-01
      • 1970-01-01
      相关资源
      最近更新 更多