如何在Emacs中列出活动的次要模式?

124

如何在emacs中列出活动的次要模式?

6个回答

145

C-h mM-x describe-mode会显示所有活动的次要模式(和主模式),以及每个模式的简要描述。


25

所有小模式命令的列表存储在变量minor-mode-list中。通常通过检查同名变量来确定它们是否处于活动状态。因此,您可以执行以下操作:

(defun which-active-modes ()
  "Give a message of which minor modes are enabled in the current buffer."
  (interactive)
  (let ((active-modes))
    (mapc (lambda (mode) (condition-case nil
                             (if (and (symbolp mode) (symbol-value mode))
                                 (add-to-list 'active-modes mode))
                           (error nil) ))
          minor-mode-list)
    (message "Active modes are %s" active-modes)))

注意:这仅适用于当前缓冲区(因为次要模式可能只在某些缓冲区中启用)。


在 map 内使用 add-to-list?有点复杂。 - jrockway
5
@jrockway 这并不是我用 Lisp 最引以为傲的时刻。 - Trey Jackson
使用boundp而不是symbolp,你可以消除condition-case - Lassi

8

describe-mode 能够列出已启用的次要模式列表,为什么我不能呢?因此,在阅读其源代码后,我意识到它从 minor-mode-listminor-mode-alist 中获取活动的次要模式列表。使用第三方 dash.el 列表操作库,我编写了以下代码:

(--filter (and (boundp it) (symbol-value it)) minor-mode-list)

例如,要禁用所有次要模式,使用-each

(--each (--filter (and (boundp it) (symbol-value it)) minor-mode-list)
        (funcall it -1))

不要忘记将次要模式列表保存在变量中,否则您将不得不重新启动Emacs或通过记忆启用它们。

4
如果您想以编程方式对所有具有特定模式的缓冲区执行某些操作,那么最好、最简约、最清晰、内置的解决方案如下:
(dolist ($buf (buffer-list (current-buffer)))
  (with-current-buffer $buf
    (when some-buffer-local-minor-or-major-mode-variable-you-want-to-find
      (message "x %s" $buf))))

它执行以下操作:
  1. 通过buffer-list检索所有缓冲区的列表,当前活动的缓冲区在列表的头部(通常是您想要的),但如果您不关心,则可以省略current-buffer参数。
  2. 循环遍历缓冲区列表,并将每个缓冲区名称分配给变量$buf
  3. 使用with-current-buffer $buf告诉Emacs,在体内运行的所有代码都应该像在缓冲区$buf中一样运行,而不是在屏幕上显示的任何缓冲区中运行。
  4. when <some mode variable>是检查模式是否启用的正确方法;您也可以使用if和其他类似的方法。无论哪种方式,目标都是检查缓冲区中是否设置了次要或主模式的主模式变量。几乎所有模式都通过“定义”模式来定义一个变量,这会自动导致它们创建一个名为模式的缓冲区局部变量,这就是它的工作原理。如果它们没有标准变量,请查看它们自己的源代码,以了解它们的“切换”代码如何确定如何切换它们的开和关状态。99%的模式使用其模式名称的变量的存在(如果它们没有,请向该模式的作者报告此错误)。例如,要检查缓冲区是否启用了空格模式,则可以说when whitespace-mode
  5. 之后,它只是将消息输出到Messages缓冲区,并显示一个“x”和启用模式的缓冲区名称。这就是您可以放置自己代码的地方,以执行任何您想要在发现的缓冲区中执行的操作。

享受吧!继续编写更好、更干净的Lisp代码吧!


2

这里有一个简单的替代代码片段,类似于其他答案中已经介绍过的一些方法:

(delq nil
  (mapcar
    (lambda (x)
      (let ((car-x (car x)))
        (when (and (symbolp car-x) (symbol-value car-x))
          x)))
    minor-mode-alist))

0
如果您只想知道缓冲区中是否激活了特定的次要模式(比如evil-mode),您可以评估以下内容:
(when (member 'evil-mode minor-mode-list)
   (message "`evil-mode' is active!"))

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