Como você lista os modos secundários ativos no emacs?

105

Como você lista os modos secundários ativos no emacs?

Somente leitura
fonte

Respostas:

125

C-h mou M-x describe-modemostra todos os modos secundários ativos (e modo principal) e uma breve descrição de cada um.

Phil
fonte
21

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).

Trey Jackson
fonte
adicionar à lista dentro do mapa? complicado.
jrockway,
4
@jrockway Não é o meu momento de maior orgulho.
Trey Jackson,
Usando em boundpvez de, symbolpvocê pode se livrar do condition-case.
Lassi
4

describe-modeposso 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-liste minor-mode-alist. Usando a dash.elbiblioteca 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.

Mirzhan Irkegulov
fonte
2

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:

  1. Recupere uma lista de todos os buffers via 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-bufferparâmetro de fora se você não se importar).
  2. Percorra a lista de buffers e atribua cada nome de buffer à variável $buf.
  3. Use with-current-buffer $bufpara dizer ao Emacs que todo o código dentro do corpo deve rodar como se estivesse rodando dentro do buffer ao $bufinvés de qualquer buffer que você esteja realmente exibindo na tela.
  4. when <some mode variable>é a maneira correta de verificar se um modo está ativado; você também pode usar ife 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.
  5. Depois disso, basta enviar uma mensagem para o buffer de Mensagens, com um "x" e o nome do buffer que tinha o modo ativo. É onde você colocaria seu próprio código, para fazer o que quisesse com o buffer descoberto.

Aproveitar! Avante para um código lisp maior e mais limpo!

gw0
fonte
2

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))
lista de leis
fonte