Como você lista os modos secundários ativos no emacs?
Como você lista os modos secundários ativos no emacs?
Respostas:
Uma lista de todos os comandos do modo secundário é armazenada na variável minor-mode-list
. Descobrir se eles estão ativos ou não geralmente é feito verificando a variável de mesmo nome. Então você pode fazer algo assim:
(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)))
Nota: isso só funciona para o buffer atual (porque os modos secundários podem ser habilitados apenas em certos buffers).
boundp
vez de, symbolp
você pode se livrar do condition-case
.
describe-mode
posso de alguma forma criar uma lista de modos secundários habilitados, por que não poderia? Então, depois de ler seu código-fonte, percebi que ele obtém a lista de modos secundários ativos de ambos minor-mode-list
e minor-mode-alist
. Usando a dash.el
biblioteca de manipulação de lista de terceiros, eu vim com este código:
(--filter (and (boundp it) (symbol-value it)) minor-mode-list)
Então, por exemplo, para desativar todos os modos secundários, use -each
:
(--each (--filter (and (boundp it) (symbol-value it)) minor-mode-list)
(funcall it -1))
Não se esqueça de salvar a lista de modos secundários em uma variável, caso contrário, você teria que reiniciar o Emacs ou habilitá-los de memória.
Se você deseja fazer algo programaticamente com todos os buffers que têm um determinado modo ativo, a melhor, mais minimalista, mais limpa e integrada solução é a seguinte:
(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))))
Ele faz o seguinte:
buffer-list
, com o buffer ativo no momento no topo da lista (então ele é tratado primeiro, geralmente o que você quer, mas deixe o current-buffer
parâmetro de fora se você não se importar).$buf
.with-current-buffer $buf
para dizer ao Emacs que todo o código dentro do corpo deve rodar como se estivesse rodando dentro do buffer ao $buf
invés de qualquer buffer que você esteja realmente exibindo na tela.when <some mode variable>
é a maneira correta de verificar se um modo está ativado; você também pode usar if
e outros métodos semelhantes. De qualquer maneira, o objetivo é verificar se a variável de modo principal de um modo menor ou maior está definida no buffer. Quase todos os modos definem uma variável por meio da "definição" de um modo, o que automaticamente faz com que eles criem uma variável local do buffer com o nome do modo, que é como isso funciona. E se eles não tiverem uma variável padrão, olhe seu próprio código-fonte para ver como seu código de "alternância" determina como ativá-los e desativá-los. 99% deles usam a existência da variável de seu modename (e se não, sugiro relatar isso como um bug para o autor do modo). Por exemplo, para verificar se um buffer tem o modo de espaço em branco ativo, você diria when whitespace-mode
.Aproveitar! Avante para um código lisp maior e mais limpo!
Aqui está um snippet alternativo simples semelhante a alguns dos métodos que já foram abordados em outras respostas:
(delq nil
(mapcar
(lambda (x)
(let ((car-x (car x)))
(when (and (symbolp car-x) (symbol-value car-x))
x)))
minor-mode-alist))