Jak wypisujesz aktywne tryby pomocnicze w emacsie?
Jak wypisujesz aktywne tryby pomocnicze w emacsie?
Odpowiedzi:
Lista wszystkich podrzędnych poleceń trybu jest przechowywana w zmiennej minor-mode-list
. Dowiedzenie się, czy są one aktywne, czy nie, odbywa się zwykle przez sprawdzenie zmiennej o tej samej nazwie. Możesz więc zrobić coś takiego:
(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)))
Uwaga: działa to tylko dla bieżącego bufora (ponieważ tryby pomocnicze mogą być włączone tylko w niektórych buforach).
boundp
zamiast symbolp
ciebie, możesz pozbyć się condition-case
.
describe-mode
mogę jakoś wymyślić listę włączonych trybów pomocniczych, dlaczego nie mogłem? Więc po przeczytaniu jego kodu źródłowego zdałem sobie sprawę, że pobiera listę aktywnych trybów pomocniczych z obu minor-mode-list
i minor-mode-alist
. Korzystając z dash.el
biblioteki do manipulacji listami innej firmy, otrzymałem ten kod:
(--filter (and (boundp it) (symbol-value it)) minor-mode-list)
Na przykład, aby wyłączyć wszystkie tryby podrzędne, użyj -each
:
(--each (--filter (and (boundp it) (symbol-value it)) minor-mode-list)
(funcall it -1))
Nie zapomnij zapisać listy pobocznych trybów w zmiennej, w przeciwnym razie będziesz musiał ponownie uruchomić Emacsa lub włączyć je z pamięci.
Jeśli chcesz programowo zrobić coś ze wszystkimi buforami, które mają aktywny określony tryb, to najlepsze, najbardziej minimalistyczne, najczystsze wbudowane rozwiązanie jest następujące:
(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))))
Wykonuje następujące czynności:
buffer-list
, z aktualnie aktywnym buforem na początku listy (więc jest traktowany jako pierwszy, zwykle to, co chcesz, ale pomiń current-buffer
parametr, jeśli nie obchodzi Cię to).$buf
.with-current-buffer $buf
do informowania Emacsa, że cały kod w treści powinien działać tak, jakby był w buforze$buf
zamiast w jakimkolwiek buforze, który naprawdę wyświetlasz na ekranie.when <some mode variable>
to właściwy sposób sprawdzenia, czy tryb jest włączony; możesz również użyć if
i innych takich metod. Tak czy inaczej, celem jest sprawdzenie, czy zmienna trybu głównego trybu pomocniczego lub głównego jest ustawiona w buforze. Prawie wszystkie tryby definiują zmienną poprzez „definiowanie” trybu, co automatycznie powoduje utworzenie zmiennej lokalnej bufora o nazwie odpowiadającej trybowi, i tak to działa. A jeśli nie mają standardowej zmiennej, spójrz na ich własny kod źródłowy, aby zobaczyć, jak ich kod „przełączający” określa, jak je włączać i wyłączać. 99% z nich korzysta z istnienia zmiennej ich nazwy modemu (a jeśli nie, sugeruję zgłosić to jako błąd autorowi trybu). Na przykład, aby sprawdzić, czy bufor ma aktywny tryb białych znaków, powiedziałbyś when whitespace-mode
.Cieszyć się! Dalej do większego i czystszego kodu lisp!
Oto prosty alternatywny fragment kodu podobny do niektórych metod, które zostały już omówione w innych odpowiedziach:
(delq nil
(mapcar
(lambda (x)
(let ((car-x (car x)))
(when (and (symbolp car-x) (symbol-value car-x))
x)))
minor-mode-alist))