【问题标题】:How to make a buffer-local key binding in Emacs?如何在 Emacs 中进行缓冲区本地键绑定?
【发布时间】:2014-12-05 17:23:03
【问题描述】:

我最近一直在研究 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 函数提供一个键绑定,但它需要特定于缓冲区,以免弄乱其他任何东西。问题是如何通过创建缓冲区进行这样的绑定。

【问题讨论】:

    标签: emacs elisp key-bindings


    【解决方案1】:

    来自 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 aka M-x describe-bindings

    【讨论】:

      【解决方案2】:

      我建议您在调用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)))))
      

      【讨论】:

        【解决方案3】:

        网络上的一些帖子建议使用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轻松关闭。

        【讨论】:

        • local-set-key 修改本地键映射,在大多数情况下是主模式键映射,这将影响使用该主模式的 所有 缓冲区。所以local-set-key 不是 缓冲区局部效应。 (它只是“本地的”,而不是每个缓冲区可见的“全局”键映射。)
        • 感谢您的回复,@phils。我对你的言论做了一些调查。当我使用iimage-mode 显示图像时,该缓冲区的主要模式是Fundamental(其他次要模式是iImgMRev)。在进行local-set-key 绑定后,我检查了所有这些模式下的键绑定,但没有一个显示出你警告我的行为。鉴于此,我认为它确实会导致缓冲区局部效应。如果我在这里遗漏了一些重要的东西,请纠正我。
        • fundamental-mode 中是正确的。它没有设置本地键盘映射,而且在这种情况下,local-set-key 似乎确实创建了一个缓冲区本地键盘映射。请注意,这不是正常行为,因为大多数主要模式都会设置(并共享)本地键盘映射。
        • 谢谢。我会留意的:)
        • 您使用本地设置键和基本模式特性的解决方案非常有用。您应该接受它作为原始问题的解决方案,以便在我们访问此页面时将其单独列出。
        【解决方案4】:

        创建次要模式:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-05-24
          • 2015-06-10
          • 2023-04-01
          • 1970-01-01
          • 2012-08-05
          • 2011-05-06
          • 1970-01-01
          相关资源
          最近更新 更多