【问题标题】:Emacs auto-minor-mode based on extension基于扩展的 Emacs 自动次要模式
【发布时间】:2012-12-06 09:58:16
【问题描述】:

我发现this question 有点关于这个话题,但是[在 emacs 中] 有没有办法根据 extension 设置一个次要模式(或其列表)?例如,很容易发现可以像这样操纵主要模式

(add-to-list 'auto-mode-alist '("\\.notes\\'" . text-mode))

而我最想做的是

(add-to-list 'auto-minor-mode-alist '("\\.notes\\'" . auto-fill-mode))

链接问题的接受答案提到了钩子,特别是temp-buffer-setup-hook。要使用它,您必须像这样向钩子添加一个函数

(add-hook 'temp-buffer-setup-hook #'my-func-to-set-minor-mode)

我的问题有两个:

  1. 有没有更简单的方法来做到这一点,类似于主要模式?
  2. 如果不是,如何为钩子编写函数?
    1. 它需要根据正则表达式检查文件路径。
    2. 如果匹配,则激活所需模式(例如auto-fill-mode)。

对解决方案的微弱和错误的尝试:

;; Enables the given minor mode for the current buffer it it matches regex
;; my-pair is a cons cell (regular-expression . minor-mode)
(defun enable-minor-mode (my-pair)
  (if buffer-file-name ; If we are visiting a file,
      ;; and the filename matches our regular expression,
      (if (string-match (car my-pair) buffer-file-name) 
      (funcall (cdr my-pair))))) ; enable the minor mode

; used as
(add-hook 'temp-buffer-setup-hook
          (lambda ()
            (enable-minor-mode '("\\.notes\\'" . auto-fill-mode))))

【问题讨论】:

  • 查看C-h v auto-mode-alist时,扩展名通常写为"\\.notes\\'"。请参阅最后的单个引用。
  • 我会被诅咒的。我在打字时错过了这一点。可能完全解释了尾随的反斜杠 -_-

标签: emacs elisp dot-emacs


【解决方案1】:

这段代码似乎给了你想要的:

(defvar auto-minor-mode-alist ()
  "Alist of filename patterns vs correpsonding minor mode functions, see `auto-mode-alist'
All elements of this alist are checked, meaning you can enable multiple minor modes for the same regexp.")

(defun enable-minor-mode-based-on-extension ()
  "Check file name against `auto-minor-mode-alist' to enable minor modes
the checking happens for all pairs in auto-minor-mode-alist"
  (when buffer-file-name
    (let ((name (file-name-sans-versions buffer-file-name))
          (remote-id (file-remote-p buffer-file-name))
          (case-fold-search auto-mode-case-fold)
          (alist auto-minor-mode-alist))
      ;; Remove remote file name identification.
      (when (and (stringp remote-id)
                 (string-match-p (regexp-quote remote-id) name))
        (setq name (substring name (match-end 0))))
      (while (and alist (caar alist) (cdar alist))
        (if (string-match-p (caar alist) name)
            (funcall (cdar alist) 1))
        (setq alist (cdr alist))))))

(add-hook 'find-file-hook #'enable-minor-mode-based-on-extension)

注意:比较是使用string-match-p 完成的,在比较期间遵循case-fold-search 设置。

【讨论】:

  • 我理解这里发生的大部分事情,虽然我收到一个错误 >Invalid regexp: "Trailing backslash"
  • 不知道如何,不知道为什么,但现在一切正常。谢谢!!
  • files.el:set-auto-mode 中,auto-mode-alist(assoc-default name auto-mode-alist 'string-match) 搜索。这可以简化并替换您的 while 循环。
  • @OlafDietsche 不是真的,我使用 while 循环来为单个文件启用多个次要模式,而 assoc-default 只会为您提供一个模式。这样做的精神是只有一种主要模式,但启用许多次要模式。
【解决方案2】:

Trey Jackson 的答案似乎是一个非常健壮且可扩展的解决方案,但我一直在寻找更简单的解决方案。以下代码将在编辑.hmmm 文件时启用虚构的hmmm-mode

(add-hook 'find-file-hook
          (lambda ()
            (when (string= (file-name-extension buffer-file-name) "hmmm")
              (hmmm-mode +1))))

【讨论】:

  • 这可以与扩展的正则表达式一起使用吗?就我而言,当找到扩展名 exexs 时,我正在尝试启用 alchemist-mode
  • @sgmonda 在这种情况下,只需按照标准方式进行即可。未经测试:(add-to-list 'auto-mode-alist ("\\.ex\\'" .alchemist-mode))`。
猜你喜欢
  • 1970-01-01
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多