Como faço para "agrupar" ganchos?

14

Há certas coisas como a exibição de espaços em branco à direita, a exibição de limites de buffer, delimitadores em cores do arco-íris e muito mais que eu gostaria de ativar na maioria dos modos, ou melhor, todos os relacionados a programação e texto (porque exibindo espaços à direita em, digamos ediff-mode, entrariam em conflito com o modo principal) em vez de usar um modo secundário globalizado com regras de exceção. Como a maioria dos modos é derivada de um prog-modeou de text-mode, adicionando a função em questão a ambos prog-mode-hooke text-mode-hookfunciona, no entanto, existem modos suficientes que não seguem esta especificação, como css-modeou LaTeX-mode.

Gostaria de definir um gancho que englobe todos esses modos por enquanto para adicionar apenas funções a um gancho. Vamos chamá-lo non-special-mode-hook(para diferenciá-lo special-mode-hook). Como eu seria capaz de criar um gancho que é executado para todos os principais modos para os quais é criado?

wasamasa
fonte

Respostas:

19

Apenas agrupe essas configurações em uma função e adicione essa função a todas as funções relevantes do gancho:

(defun my-non-special-mode-setup ()
  (setq show-trailing-whitespace t)
  ...)
(dolist (hook '(prog-mode-hook text-mode-hook css-mode-hook ...))
  (add-hook hook 'my-non-special-mode-setup))

Nenhuma outra maneira de fazer isso seria mais concisa: aconteça o que acontecer, em algum lugar você terá uma lista de permissões ou uma lista negra de modos. Na prática, você encontrará apenas alguns modos que precisam ser adicionados à lista, então sugiro apenas manter as coisas simples.

Na minha própria configuração, eu uso exatamente esse truque para unificar a configuração de vários modos orientados a lisp.

sanityinc
fonte
Obrigado, acho que vou adaptar essa solução para outros grupos úteis (como os lispy) também.
wasamasa
1
É exatamente o que eu faço: github.com/purcell/emacs.d/blob/…
sanityinc
1
Excelente, você poderia adicionar o URL à sua resposta? Acredito que o trecho destacado não apenas explica muito bem o uso real, mas também demonstra um uso adicional, como o uso de um "gancho" relacionado ao Emacs Lisp como subconjunto de um "gancho" maior e como alguém criaria automaticamente nomes de ganchos a partir dos principais modos existentes com derived-mode-hook-name.
wasamasa
Gosto mais do que o meu, apenas para o (dolist ...)vs (add-hook ...)<repeat>. Eu só ia ficar com a minha quando mantendo específicos de modo altera separado (arquivo-per-mode, use-package, el-get). Ambas são soluções all-in-one-place, mas sob diferentes pontos de vista.
Jonathan Leech-Pepin
Esteja ciente de que se você não fornecer um APPENDargumento não nulo add-hookaqui, os ganchos serão chamados na ordem inversa da ordem de lista que você fornecer. Nada de errado com isso; apenas esteja ciente disso, caso a ordem seja importante.
Desenhou
5

Você pode adicionar uma função para after-change-major-mode-hook, que verifica se o novo modo é interessante (possivelmente até (not (derived-mode-p 'special-mode))) e, se for, é executado non-special-mode-hook.

legoscia
fonte
Isso soa bem bacana (depois que alguém descobriu todos os modos "não especiais", pois há alguns que apenas usam fundamental-mode, mas fazem mais do que apenas exibir texto), mas um pouco demais para o meu gosto. Daí o voto positivo.
wasamasa
4

Eu me encontrei frequentemente fazendo o padrão do @ sanityinc de agrupar minhas configurações e ativações de modo menor em um estado de desintegração e percorrer ganchos para chamá-lo, mas eu queria uma abordagem mais limpa, então escrevi esta macro:

(defmacro hook-modes (modes &rest body)
  (declare (indent 1))
  `(--each ,modes
     (add-hook (intern (format "%s-hook" it))
               (lambda () ,@body))))

Nota: Sou a dash.elfavor da limpeza, mas ela pode ser facilmente adaptada para uso (dolist).

Em seguida, você pode definir modos agrupados como variáveis ​​de lista e usá-lo da seguinte maneira:

(defvar progish-modes
  '(prog-mode css-mode sgml-mode))

(hook-modes progish-modes
  (highlight-symbol-mode)
  (highlight-symbol-nav-mode))
waymondo
fonte
1
Observe que aqui você pode usar derived-mode-hook-namepara obter o nome da variável de gancho de um modo, evitando assim o interntruque.
Sanityinc 03/04/19
@sanityinc TIL derived-mode-hook-name. boa dica!
waymondo
1

Em vez de definir um novo gancho que funcione para todos esses modos não derivados , você pode fazer o seguinte.

(defun run-my-hooks ()
  "Run all the following functions in the hook"
  (smartparens-mode 1)
  (whitespace-mode 1)
  (my-needed-mode 1)
  ...)

(add-hook 'specific-mode-hook 'run-my-hooks)
(add-hook 'another-mode-hook 'run-my-hooks)

Você ainda precisará adicioná-lo a todos os modos, mas definindo sua função para incluir todos os modos, você precisará alterar apenas uma definição ao adicionar / remover recursos adicionais.

Jonathan Leech-Pepin
fonte
-2

Talvez você possa tentar o seguinte:

(setq lisp-dialects-mode-hook '(lisp-mode-hook
                            lisp-interaction-mode-hook
                            emacs-lisp-mode-hook
                            ;; common-lisp-mode-hook
                            scheme-mode-hook
                            clojure-mode-hook
                            cider-repl-mode-hook
                            ))

(add-hook 'lisp-dialects-mode-hook 'func)
stardiviner
fonte