如何在Emacs中进行缓冲区本地密钥绑定?

如何在Emacs中进行缓冲区本地密钥绑定?,emacs,elisp,key-bindings,Emacs,Elisp,Key Bindings,我最近一直在研究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) (ii

我最近一直在研究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)))
(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)))

它会生成一个缓冲区,并将图像作为参数传递,但是关闭缓冲区需要点击C-xk并返回,这在一段时间后开始变得很麻烦。简化此类临时缓冲区关闭的方法是为
kill this buffer
函数提供一个键绑定,但它需要是特定于缓冲区的,以避免弄乱任何其他内容。问题是如何创建一个缓冲区来进行这样的绑定。

我被网络上一些建议使用
本地键绑定的帖子误导了,但不知怎么的,它对我不起作用-当显示图像并检查键绑定时,我选择的
q
无效。经过一些实验和深入研究
elisp
参考资料后,我发现我需要使用
localset key
。现在我的函数如下所示:

(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)))
(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键轻松关闭。

我建议您在调用
切换到缓冲区后添加对
特殊模式的调用。
从长远来看,您需要使用自己的主模式,因此您需要:

(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)))))
从EmacsWiki:

对于缓冲区本地键,您不能使用
本地设置键
,除非您想修改所讨论的整个主模式的键映射:
本地设置键
是主模式的本地键,而不是缓冲区的本地键

对于缓冲区本地修改,请改用此选项:

(使用本地映射(复制keymap foo模式映射))
(本地设置键“d”的某些功能)
作者:TiagoSaboga


要检查更改,请键入
C-h b
aka
M-x descripe bindings
创建次要模式:

(define-minor-mode my-mode "my doc" nil nil (make-sparse-keymap))

然后,您可以使用此模式的
my mode map
来定义键绑定。使用
(我的模式)

本地设置键激活模式
修改本地键映射,在大多数情况下是主模式键映射,这将影响使用该主模式的所有缓冲区。因此,
local set key
不是缓冲区局部效果。(它只是“本地”的,而不是每个缓冲区都可以看到的“全局”键映射。)感谢您的回复,@phils。我对你的话做了一些调查。当我使用
iimage模式
显示图像时,该缓冲区的主要模式是
基本模式
(其他次要模式是
iImg
MRev
)。在进行
本地设置键
绑定后,我检查了所有这些模式下的键绑定,没有一个显示出您警告过我的行为。从这个角度看,它确实会产生缓冲区局部效应。如果我在这里遗漏了一些重要的内容,请纠正我。在
基本模式下
这是正确的。它没有设置本地密钥映射,而且在这种情况下,
localset key
似乎确实创建了一个缓冲区本地密钥映射。请注意,这不是正常行为,因为大多数主要模式都会设置(并共享)本地密钥映射。谢谢。我会关注它:)您使用本地设置键和基本模式的特性的解决方案非常有用。您应该接受它作为您原始问题的解决方案,以便在我们访问此页面时将其选中。