Как вы перечислите активные второстепенные режимы в Emacs?

Как вы перечислите активные второстепенные режимы в Emacs?

6 ответов

Решение

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 или включить их по памяти.

Если вы хотите программно что-то сделать со всеми буферами, для которых активен определенный режим, то лучшее, самое минималистичное, самое чистое встроенное решение выглядит следующим образом:

(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. После этого он просто выводит сообщение в буфер сообщений с "x" и именем буфера, в котором был активен режим. Там вы бы поместили свой собственный код, чтобы делать то, что вы хотели сделать с обнаруженным буфером.

Наслаждайтесь! Вперед к большему и более чистому коду!

Вот простой альтернативный фрагмент, похожий на некоторые методы, которые уже были рассмотрены в других ответах:

(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!"))
Другие вопросы по тегам