Wie "gruppiere" ich Hooks?

14

Es gibt bestimmte Dinge wie die Anzeige von abschließenden Leerzeichen, die Anzeige von Puffergrenzen, regenbogenfarbene Begrenzer und vieles mehr, die ich in den meisten Modi oder vielmehr in allen programmier- und textbezogenen Modi aktivieren möchte (weil abschließende Leerzeichen in, B. ediff-modemit dem Hauptmodus kollidieren, anstatt einen globalisierten Nebenmodus mit Ausnahmeregeln zu verwenden. Da die meisten Modi von einem prog-modeoder abgeleitet text-modesind und die betreffende Funktion zu beiden hinzugefügt wird prog-mode-hookund text-mode-hookfunktioniert, gibt es jedoch genügend Modi, die dieser Spezifikation nicht folgen, wie z. B. css-modeoder LaTeX-mode.

Ich möchte einen Hook definieren, der vorerst alle diese Modi umfasst, um nur einem Hook Funktionen hinzuzufügen. Nennen wir es non-special-mode-hook(um es zu unterscheiden special-mode-hook). Wie kann ich einen solchen Hook erstellen, der für alle Hauptmodi ausgeführt wird, für die er gemacht ist?

Wasamasa
quelle

Antworten:

19

Gruppieren Sie diese Einstellungen einfach zu einer Funktion und fügen Sie diese Funktion allen relevanten Hook-Funktionen hinzu:

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

Kein anderer Weg, dies zu tun, wäre prägnanter: Was auch immer passiert, irgendwo werden Sie entweder eine Whitelist oder eine Blacklist von Modi haben. In der Praxis gibt es nur wenige Modi, die zur Liste hinzugefügt werden müssen. Ich empfehle daher, die Dinge einfach zu halten.

In meiner eigenen Konfiguration verwende ich genau diesen Trick , um die Konfiguration mehrerer lisp-orientierter Modi zu vereinheitlichen.

sanityinc
quelle
Vielen Dank, ich denke, ich werde diese Lösung auch für andere nützliche Gruppen (wie die Lispy-Gruppen) anpassen.
Wasamasa
1
Genau das mache ich selbst: github.com/purcell/emacs.d/blob/…
sanityinc
1
Hervorragend, könnten Sie vielleicht die URL zu Ihrer Antwort hinzufügen? Ich glaube, das hervorgehobene Snippet erklärt nicht nur die tatsächliche Verwendung sehr gut, sondern demonstriert auch die weitere Verwendung, beispielsweise die Verwendung eines Emacs-Lisp-bezogenen "Hooks" als Teilmenge eines größeren "Hooks" und die automatische Erstellung von Hook-Namen aus vorhandenen Hauptmodi mit derived-mode-hook-name.
Wasamasa
Ich mag dies mehr als meins, nur für die (dolist ...)vs (add-hook ...)<repeat>. Ich würde nur mit meinem haften , wenn Beibehaltungsmodus spezifischen getrennte Änderungen (Datei-per-Modus use-package, el-get). Beide Lösungen sind alles aus einer Hand, jedoch aus unterschiedlichen Blickwinkeln.
Jonathan Leech-Pepin
Beachten Sie, dass die Hooks in umgekehrter Reihenfolge zu der von Ihnen angegebenen Listenreihenfolge aufgerufen werden , wenn Sie hier kein Nicht-Null- APPENDArgument angeben add-hook. Daran ist nichts auszusetzen. seien Sie sich dessen bewusst, falls die Bestellung wichtig ist.
Drew
5

Sie können eine Funktion hinzufügen after-change-major-mode-hook, die prüft, ob der neue Modus interessant ist (möglicherweise durchgehend (not (derived-mode-p 'special-mode))) und wenn ja, ausgeführt wird non-special-mode-hook.

Legoscia
quelle
Das klingt ziemlich geschickt (wenn man erst einmal alle "unspezifischen" Modi herausgefunden hat, da es einige gibt, die nur fundamental-modeText verwenden , aber mehr als nur anzeigen), aber ein bisschen zu magisch für meinen Geschmack. Daher die Gegenstimme.
Wasamasa
4

Ich habe oft das @ sanityinc-Muster ausgeführt, bei dem ich meine Einstellungen und Nebenmodusaktivierungen in eine Defun-Funktion eingebunden und Hooks durchgeschleift habe, um sie aufzurufen, aber ich wollte einen saubereren Ansatz, also habe ich dieses Makro geschrieben:

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

Hinweis: Ich bin dash.elfür die Sauberkeit, aber es könnte leicht angepasst werden, um zu verwenden (dolist).

Dann können Sie gruppierte Modi als Listenvariablen definieren und wie folgt verwenden:

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

(hook-modes progish-modes
  (highlight-symbol-mode)
  (highlight-symbol-nav-mode))
waymondo
quelle
1
Beachten Sie, dass Sie hier verwenden können derived-mode-hook-name, um den Namen der Hook-Variablen eines Modus abzurufen, wodurch der internTrick vermieden wird .
Sanityinc
@sanityinc TIL derived-mode-hook-name. schöner tipp!
Waymondo
1

Anstatt einen neuen Hook zu definieren, der für alle diese nicht abgeleiteten Modi funktioniert , können Sie Folgendes tun.

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

Sie müssen es weiterhin allen Modi hinzufügen, aber indem Sie Ihre Funktion so definieren, dass sie alle Modi umfasst, müssen Sie nur eine Definition ändern, wenn Sie zusätzliche Funktionen hinzufügen oder entfernen.

Jonathan Leech-Pepin
quelle
-2

Vielleicht können Sie dies versuchen:

(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
quelle