Як ви перераховуєте активні другорядні режими в 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))