Как вы перечисляете активные второстепенные режимы в emacs?
Как вы перечисляете активные второстепенные режимы в emacs?
Ответы:
Список всех команд второстепенного режима хранится в переменной 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)))
Примечание: это работает только для текущего буфера (поскольку второстепенные режимы могут быть включены только в определенных буферах).
boundp
вместо symbolp
вы можете избавиться от condition-case
.
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))
Не забудьте сохранить список второстепенных режимов в переменной, иначе вам придется перезапустить Emacs или включить их по памяти.
Если вы хотите что-то программно сделать со всеми буферами, в которых активен определенный режим, то лучшее, самое минималистичное и чистое встроенное решение выглядит следующим образом:
(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))