添加键盘绑定到现有的Emacs模式

时间:2010-03-12 00:08:12

标签: python emacs keyboard-shortcuts elisp

我正在尝试首次修改Emacs。我录制了一个小键盘宏,让Emacs把它作为elisp吐出来,结果是:

(setq add-docstring
    "\C-rdef\C-n\C-a\C-m\C-p\C-i\C-u6\"\C-u3\C-b")
(global-set-key "\C-c\C-d" 'add-docstring)

但是,搜索Emacs参考文献显示 C-c C-d 已经在diff模式下绑定。我没有计划使用diff模式,但未来是不可知的,我不想为自己设置陷阱。所以我希望这个键绑定只能在python模式下运行,它试图帮助我添加文档字符串。

在我的/usr/share/emacs/23.whatever/list/progmodes中,我找到了python.elcpython.el.gz。我解压缩python.el.gz并获得了elisp文件的可读版本。但是,现在,文档对我来说变得不透明了。

如何将我的键绑定添加到python模式,而不是全局?

对于奖励积分,是否可以将更改应用于python模式而无需重新启动emacs或关闭打开的文件?这是自我修改的编辑器,我认为这是可能的。

2 个答案:

答案 0 :(得分:15)

事实证明, C-c C-d 已绑定在python-mode'python-pdbtrack-toggle-stack-tracking)中,因此您可能需要重新选择键绑定。

注意:如果您只想剪切/粘贴解决方案,请跳到答案的末尾。继续阅读,了解如何到达那里 - 如果你想再做一次。

宏是一个好的开始,但你拥有的东西不会很好用。要获得可以绑定到某个键的内容,请尝试该宏的 M-x insert-kbd-macro ,然后您将获得:

(fset 'add-docstring
   (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ("def ...unprintable characters...6\"3" 0 "%d")) arg)))

(嗯....不可打印的字符,我不能剪切/粘贴到SO中,但你可以自己做以获得正确的东西)。稍微改动,你得到的就是这个:

(fset 'add-docstring
      (lambda (&optional arg)
        "Keyboard macro."
        (interactive "p")
        (kmacro-exec-ring-item `(,(kbd "C-r def C-n C-a C-m C-p C-i C-u 6 \" C-u 3 C-b") 0 "%d")
                               arg)))

这是第一步。通过上述操作,您可以执行M-x add-docstring并获得所需的行为。

下一步是你问的问题 - 如何在本地绑定密钥。您感兴趣的keybindings begins here文档是Local Keymaps section,其中包含以下内容:

(add-hook 'python-mode-hook
          (lambda () (define-key python-mode-map (kbd "C-c C-d") 'add-docstring)))

这将设置一个匿名函数,在python-mode打开时调用,该函数执行一项操作 - 它在keymap中专门为python-mode设置所需的键绑定。

如果你仔细阅读Keymaps section,你会发现Emacs遵循的惯例是只有用户才能将逗号绑定到 Cc a ,其中 a 是任何小写或大写字母(例如 Cc d Cc T Cc p 都可用),并且包约束模式特定的绑定到< kbd> Cc%,其中是任何标点字符或控制键(例如 Cc Cc Cc [ Cc Cz )。

因此,如果您将绑定更改为 C-c d ,那么您几乎可以保证不会与任何包冲突。 Emacs附带的python.el确实遵循这些惯例,Emacs附带的大多数(全部?)包也是如此。

您会注意到我使用kbd来读取键序列。它是便携式的,我觉得它更容易阅读。

还有其他一些方法可以清理它:

  1. 将自定义设置放在named function
  2. rewrite the macro in elisp
  3. 使用eval-after-load代替钩子(请参阅此问题)
  4. 以下是我为#1做的事情,它为您提供了一个放置其他自定义项的便利位置:

    (add-hook 'python-mode-hook 'my-python-customizations)
    (defun my-python-customizations ()
      "set up my personal customizations for python mode"
      ;; put other customizations in here
      (define-key python-mode-map (kbd "C-c C-d") 'add-docstring))
    (defun add-docstring (&optional arg)
      "Keyboard macro."
      (interactive "p")
      (kmacro-exec-ring-item `(,(kbd "C-r def C-n C-a C-m C-p C-i C-u 6 \" C-u 3 C-b") 0 "%d")
                             arg))
    

    如果您愿意,可以稍后使用命名函数进行(remove-hook 'python-mode-hook 'my-python-customizations)。另外,如果你查看钩子的值( Ch v python-mode-hook RET ),很明显会调用什么(匿名函数更长,更难以阅读)。

    对于奖励积分,将代码粘贴到.emacs M-x eval-region 后,这将告诉Emacs评估该地区的代码。要查看现有python缓冲区中的更改,您只需打开一个新的python文件/缓冲区,这将触发键绑定更改 - 这对所有python缓冲区都是通用的。

    快乐的黑客攻击。

答案 1 :(得分:4)

首先,不要乱用python.el。你想要做的是为python模式创建自己的自定义绑定。这通常在您的主目录中的.emacs文件中完成。

在该文件中添加如下内容(我没有对此进行测试 - 因此语法中可能存在一些错误,我自己也不使用python)

(add-hook 'python-mode-hook
     '(lambda () (define-key python-mode-map "\C-c\C-d" 'add-doc-string)))

这是使用钩子机制。每次调用python模式时都会调用它。此功能仅将C-c C-d绑定到您的add-doc-string函数。

这个答案非常简短。阅读emacs文档中的.emacs文件,自定义项和挂钩。