如何在Emacs中设置本地缓冲区键绑定?

8

最近我一直在开发一个 Emacs 次要模式,其中的一部分功能是在单独的缓冲区中显示图像。到目前为止,我一直在使用这样的一个函数:

(defun create-buffer-with-image (name)
  (let ((buffer (generate-new-buffer name))
        (image (get-svg-for-kanji-code name)))
    (switch-to-buffer buffer)
    (turn-on-iimage-mode)
    (iimage-mode-buffer t)
    (insert-image image)))

这段代码使用传入的图像生成缓冲区,但关闭缓冲区需要按下 C-x kReturn,久而久之变得繁琐。简化关闭临时缓冲区的方法是绑定一个键来执行 kill-this-buffer 函数,但需要进行缓冲区特定的设置,以免影响其他内容。问题在于如何在创建缓冲区时进行此类绑定。

4个回答

9

来自EmacsWiki:https://www.emacswiki.org/emacs/BufferLocalKeys

对于缓冲区本地键,你不能使用local-set-key,除非你想要修改有问题的整个主模式的键映射: local-set-key是局限于一个主模式,而不是一个缓冲区。

对于缓冲区本地修改,请改用以下方法:

(use-local-map (copy-keymap foo-mode-map))
(local-set-key "d" 'some-function)

作者:TiagoSaboga


要检查更改,请键入C-h b,也可以使用M-x describe-bindings命令。


3

我建议在调用switch-to-buffer后添加一个调用special-mode的语句。 从长远来看,您可能需要使用自己的主模式,因此您应该执行以下操作:

(define-derived-mode my-image-mode special-mode "MyImage"
  "My own major mode to display images."
  ;; We could add more things here
  )

(defun create-buffer-with-image (name)
  (with-current-buffer (generate-new-buffer name)
    (my-image-mode)
    (let ((image (get-svg-for-kanji-code name)))
      (turn-on-iimage-mode)
      (iimage-mode-buffer t)
      (insert-image image)
      (pop-to-bffer (current-buffer)))))

2

我有些被网上一些帖子误导,它们建议使用local-key-binding,但不知为何对我无效 - 当图像显示并检查键绑定时,我的选择q没有生效。经过一些实验和查阅elisp参考资料,我发现我需要使用local-set-key。因此,现在我的函数看起来像这样:

(defun create-buffer-with-image (name)
  (let ((buffer (generate-new-buffer name))
        (image (get-svg-for-kanji-code name)))
    (switch-to-buffer buffer)
    (local-set-key (kbd "q") 'kill-this-buffer)
    (turn-on-iimage-mode)
    (iimage-mode-buffer t)
    (insert-image image)))

新创建的图像缓冲区可以通过按下q键轻松关闭。


2
local-set-key 修改本地键映射,大多数情况下是主模式键映射,这将影响使用该主模式的所有缓冲区。因此,local-set-key 不是缓冲区本地效果。(它只是相对于“全局”键映射而言的“本地”)。 - phils
2
感谢您的回复,@phils。我对您的评论进行了一些调查。当我使用iimage-mode显示图像时,该缓冲区的主要模式为Fundamental(附加的次要模式为iImgMRev)。在进行local-set-key绑定后,我检查了所有这些模式中的按键绑定,但没有一个显示出您警告我的行为。在我看来,这实际上会导致缓冲区本地效果。如果我漏掉了重要的东西,请纠正我。 - Wojciech Gac
1
fundamental-mode 中是正确的。它不设置本地键映射,而且在这种情况下,local-set-key 确实会创建一个缓冲区本地键映射。只需注意,这不是正常行为,因为大多数主要模式都设置(并共享)本地键映射。 - phils
谢谢。我会关注它的 :) - Wojciech Gac
1
你使用local-set-key和fundamental-mode的解决方案非常有用。你应该接受它作为原问题的解决方案,这样当我们访问此页面时,它将被突出显示。 - phs

0
创建一个小模式:
(define-minor-mode my-mode "my doc" nil nil (make-sparse-keymap))

然后,您可以使用此模式的my-mode-map来定义您的按键绑定。使用(my-mode)激活该模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接