【问题标题】:File-specific key-binding in emacsemacs 中的文件特定键绑定
【发布时间】:2014-02-24 13:16:11
【问题描述】:

是否可以在 emacs 中定义文件特定的键绑定? 我想可以创建一个次要模式并在特定文件打开时加载它,但只有一个键绑定似乎有点过头了。

【问题讨论】:

  • (global-set-key [f5] (lambda () (interactive) (if (equal (buffer-name) "*scratch*") (message "Congratulations -- you are executing F5 in buffer %s" (buffer-name))))) 或者,您可以使用buffer-file-name,然后使用文件路径。您也可以使用文件扩展名来执行此操作 - 例如,(if . . . (file-name-extension input-filename)

标签: emacs key-bindings


【解决方案1】:

如果您将代码组合到local-set-keyBuffer-locally overriding minor-mode key bindings in Emacs,那么您最终可能会得到这样的结果:

(defun my-buffer-local-set-key (key command)
  (interactive "KSet key buffer-locally: \nCSet key %s buffer-locally to command: ")
  (let ((oldmap (current-local-map))
        (newmap (make-sparse-keymap)))
    (when oldmap
      (set-keymap-parent newmap oldmap))
    (define-key newmap key command)
    (use-local-map newmap)))

然后,根据 Barmar 的回答:

;; Local Variables:
;; eval: (my-buffer-local-set-key (kbd "C-c C-c") 'foo)
;; End:

请注意,次要模式地图优先于本地地图。

【讨论】:

    【解决方案2】:

    File Local Variables 部分中使用eval:

    ;;; Local Variables:
    ;;; eval: (local-set-key ...)
    

    【讨论】:

    • 这不是设置当前major-mode的绑定吗?那么这种模式的其他缓冲区也会得到绑定吗?
    • 嗯,你是对的,本地键映射通常由同一主模式下的所有缓冲区共享。基本思路还是对的:编写一些代码在当前缓冲区中进行绑定,然后在Local Variables 部分中调用它。
    【解决方案3】:

    闻起来像是你做错了——这是我的猜测。如果您有一个适合给定键绑定的特定文件缓冲区,则专门为它定义一个模式并将该键绑定到该模式的键映射中。让该模式继承自您喜欢的任何其他模式。

    例如:

    (define-derived-mode my-file-mode org-mode "My file mode")
    (define-key 'my-file-mode-map (kbd "SPC") #'org-toggle-checkbox)
    

    你并没有真正描述你的上下文:你如何访问这个文件(C-x C-f 别的东西)?为什么只有这个文件——它有什么特别之处?钥匙是干什么用的?所以很难给你任何有用的建议。

    如果你真的想让这个特定文件的某些键有不同的行为,那么可以定义一个访问文件的命令(无论你想访问它),然后在其所有文本上创建一个覆盖,并使用覆盖属性keymap 在任何地方添加您的绑定。这当然听起来很愚蠢,但就目前而言,你的问题也是如此。

    Emacs 使用 缓冲区。缓冲区处于模式。在这种情况下,文件几乎没有意义。一旦文件被访问,它的 buffer 就是你想要使用的。

    这就是@Barmar 试图根据缓冲区及其模式来回答的原因。您显然不希望这是针对给定模式的,除非我猜该模式特定于该文件。在这种情况下,请定义一个(仅)应用于该文件的模式。

    澄清您的问题,也许我们可以为您提供更多帮助。

    (听起来可能是XY problem。)

    【讨论】:

    • 如果您真正解释了执行您提到的操作的方法,您的回答会更有用。听起来不错,我愿意尝试,但我对创建模式和更改键映射不是很熟悉。
    • 我的主要建议是直接陈述您的问题,例如,提供更多上下文,而不是询问您认为解决方案应该如何做(参见 XY 问题链接)。我建议这样做,因为我以某种方式感觉到你不需要你认为你需要的东西。无论如何,wrt 使用具有属性keymap 的覆盖,请参阅 Elisp 手册,节点 Overlay Properties。但我的猜测是@phils 的答案是更好的方法。
    【解决方案4】:

    设置一个次要模式并在打开特定文件时自动加载它实际上比我想象的要简单。

    模式文件大致如下:

    (define-minor-mode magic-mode
      "Provide functions to do magic."
      :lighter " !!!"
      :keymap (let ((map (make-sparse-keymap)))
                (define-key map (kbd "M-z") 'xyzzy)
                map)
    )
    
    
    (defun xyzzy()
      "Use at your own risk"
      (message "Nothing happens.")
      )
    
    
    
    (provide 'magic-mode)
    

    它必须放在 .emacs 将要查看的某个位置,并且以下行将添加到 .emacs 中:

    (require magic-mode)
    

    最后,应在文件末尾添加以下块,该块应使用特定命令:

    ;; Local Variables:
    ;; eval: (magic-mode)
    ;; End:
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-15
      相关资源
      最近更新 更多