python - 将键盘绑定(bind)添加到现有的 Emacs 模式

标签 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 已经绑定(bind)在 diff 模式中。我不计划使用 diff 模式,但 future 是不可知的,我不想给自己设下陷阱。所以我希望这个键绑定(bind)只在 python 模式下运行,它会尝试帮助我添加文档字符串。

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

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

是否可以在不重新启动 emacs 或关闭打开的文件的情况下将更改应用到 python 模式以获得奖励积分?它是自修改编辑器,我认为它很有可能成为可能。

最佳答案

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

注意:如果您只想剪切/粘贴解决方案,请跳至答案末尾。请继续阅读有关如何到达那里的说明 - 以防您想再次这样做。

宏是一个良好的开端,但您所拥有的将无法正常工作。要获得可以绑定(bind)到某个键的内容,请为该宏尝试 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 并获得您想要的行为。

下一步就是您所要求的 - 如何在本地绑定(bind)到 key 。 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 开启时调用,该函数只做一件事——它在键盘映射中专门为 python-mode 设置你想要的键绑定(bind).

如果您阅读 Keymaps section仔细观察,您会发现 Emacs 遵循只有用户才能将逗号绑定(bind)到 C-c a 的约定,其中 a 是任何小写或大写字母(例如 C-c d C-c T C-c p 都可用),并且包将特定于模式的绑定(bind)限制为 C-c %,其中 % 是任何标点符号或控制键(例如 C-c C-c C-c [ C-c C-z)。

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

你会注意到我使用了 kbd读取键序列。它是可移植的,我发现它更容易阅读。

您还可以做更多的事情来清理它:

  1. 将定制放在 named function
  2. rewrite the macro in elisp
  3. 使用eval-after-load而不是钩子(Hook)(见这个问题)

这是我为 #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)。此外,如果您查看 Hook 的值 (C-h v python-mode-hook RET),很明显调用了什么(匿名函数更长且更难阅读)。

为了加分,将代码粘贴到 .emacs 后执行 M-x eval-region,这将告诉 Emacs 评估该区域中的代码。要查看现有 python 缓冲区中的更改,您只需打开一个新的 python 文件/缓冲区,这将触发键绑定(bind)更改——这对所有 python 缓冲区都是通用的。

祝你黑客愉快。

关于python - 将键盘绑定(bind)添加到现有的 Emacs 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2429603/

相关文章:

shell - 自定义 shell 自动从 .emacs 启动

emacs - 如何从 Emacs 中的次要模式键盘映射中删除键?

python - 从 Pandas Dataframe 创建嵌套字典

python - 使用 boto3 dynamodb 客户端时出现 FilterExpression 语法错误

python - Pandas :用另一列的值替换零值

Python Pandas NLTK 带有 Groupby 的数据框列中标记化单词的频率分布

emacs - 在 emacs 中,如何更改默认的 so ctrl-c 复制和 ctrl-v 粘贴?

emacs - 找出降低 emacs 速度的模块

visual-studio - Visual Studio 上下文菜单快捷方式

java - 可以修改 Eclipse 的 Organize Import (ctrl+shift+o) 命令对静态导入的处理吗?