Как вы перечисляете активные второстепенные режимы в emacs?
-
19-09-2019 - |
Вопрос
Как вы перечисляете активные второстепенные режимы в 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))
Не забудьте сохранить список второстепенных режимов в переменной, иначе вам пришлось бы перезапустить Emacs или включить их по памяти.
Вот простой альтернативный фрагмент, похожий на некоторые методы, которые уже рассматривались в других ответах:
(delq nil
(mapcar
(lambda (x)
(let ((car-x (car x)))
(when (and (symbolp car-x) (symbol-value car-x))
x)))
minor-mode-alist))
Если ты хочешь программно сделайте что-нибудь со всеми буферами, у которых активен определенный режим, тогда лучшим, самым минималистичным, самым чистым встроенным решением будет следующее:
(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, что весь код в теле должен выполняться так, как если бы он выполнялся внутри buffer$buf
вместо любого буфера, который вы на самом деле отображаете на экране. when <some mode variable>
это правильный способ проверить, включен ли режим;вы также можете использоватьif
и другие подобные методы.В любом случае, цель состоит в том, чтобы проверить, установлена ли в буфере переменная основного режима младшего или основного режима.Почти все режимы определяют переменную через "определение" режима, который автоматически заставляет их создавать локальную переменную буфера, названную в честь режима, вот как это работает.И если у них нет стандартной переменной, посмотрите на их собственный исходный код, чтобы увидеть, как их код "переключения" определяет, как их включать и выключать.99% из них используют существование переменной их modename (и если они этого не делают, я предлагаю сообщить об этом автору режима как об ошибке).Например, чтобы проверить, активен ли в буфере режим пробелов, вы бы сказалиwhen whitespace-mode
.- После этого он просто выводит сообщение в буфер сообщений с символом "x" и именем буфера, в котором был активен режим.Вот куда вы поместили бы свой собственный код, чтобы делать с обнаруженным буфером все, что вы хотели бы сделать.
Наслаждайтесь!Вперед к большему и более чистому коду на lisp!