如何在emacs中列出活动的次要模式?
C-h m
或M-x describe-mode
会显示所有活动的次要模式(和主模式),以及每个模式的简要描述。
所有小模式命令的列表存储在变量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)))
注意:这仅适用于当前缓冲区(因为次要模式可能只在某些缓冲区中启用)。
describe-mode
能够列出已启用的次要模式列表,为什么我不能呢?因此,在阅读其源代码后,我意识到它从 minor-mode-list
和 minor-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))
(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))))
buffer-list
检索所有缓冲区的列表,当前活动的缓冲区在列表的头部(通常是您想要的),但如果您不关心,则可以省略current-buffer
参数。$buf
。with-current-buffer $buf
告诉Emacs,在体内运行的所有代码都应该像在缓冲区$buf
中一样运行,而不是在屏幕上显示的任何缓冲区中运行。when <some mode variable>
是检查模式是否启用的正确方法;您也可以使用if
和其他类似的方法。无论哪种方式,目标都是检查缓冲区中是否设置了次要或主模式的主模式变量。几乎所有模式都通过“定义”模式来定义一个变量,这会自动导致它们创建一个名为模式的缓冲区局部变量,这就是它的工作原理。如果它们没有标准变量,请查看它们自己的源代码,以了解它们的“切换”代码如何确定如何切换它们的开和关状态。99%的模式使用其模式名称的变量的存在(如果它们没有,请向该模式的作者报告此错误)。例如,要检查缓冲区是否启用了空格模式,则可以说when whitespace-mode
。享受吧!继续编写更好、更干净的Lisp代码吧!
这里有一个简单的替代代码片段,类似于其他答案中已经介绍过的一些方法:
(delq nil
(mapcar
(lambda (x)
(let ((car-x (car x)))
(when (and (symbolp car-x) (symbol-value car-x))
x)))
minor-mode-alist))
evil-mode
),您可以评估以下内容:(when (member 'evil-mode minor-mode-list)
(message "`evil-mode' is active!"))
boundp
而不是symbolp
,你可以消除condition-case
。 - Lassi