Jak „grupować” haczyki?

14

Są pewne rzeczy, takie jak wyświetlanie końcowych białych znaków, wyświetlanie granic buforów, tęczowe separatory i wiele innych, które chciałbym włączyć w większości trybów, a raczej wszystkie związane z programowaniem i tekstem (ponieważ wyświetlanie końcowych spacji w, powiedzmy ediff-mode, koliduje z trybem głównym) zamiast używać zglobalizowanego trybu podrzędnego z regułami wyjątków. Ponieważ większość trybów pochodzi z jednego z prog-modelub text-mode, dodanie omawianej funkcji do obu prog-mode-hooki text-mode-hookdziała, jednak jest wystarczająca liczba trybów niezgodnych z tą specyfikacją, takich jak css-modelub LaTeX-mode.

Chciałbym zdefiniować hak, który na razie obejmuje wszystkie te tryby, aby dodać funkcje tylko do jednego haka. Nazwijmy to non-special-mode-hook(aby odróżnić special-mode-hook). Jak mogę stworzyć taki hak, który będzie uruchamiany dla wszystkich głównych trybów, dla których został stworzony?

wasamasa
źródło

Odpowiedzi:

19

Po prostu zgrupuj te ustawienia razem w funkcję i dodaj tę funkcję do wszystkich odpowiednich funkcji przechwytujących:

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

Żaden inny sposób na zrobienie tego nie byłby bardziej zwięzły: cokolwiek się stanie, gdzieś będziesz mieć białą listę lub czarną listę trybów. W praktyce znajdziesz tylko kilka trybów, które wymagają dodania do listy, więc sugeruję po prostu uproszczenie.

W mojej własnej konfiguracji używam właśnie tej sztuczki, aby ujednolicić konfigurację kilku trybów zorientowanych na seplenienie.

sanityinc
źródło
Dziękuję, myślę, że dostosuję to rozwiązanie również do innych przydatnych grup (takich jak te lispy).
wasamasa
1
Właśnie to robię sam: github.com/purcell/emacs.d/blob/…
sanityinc
1
Doskonale, czy możesz dodać adres URL do swojej odpowiedzi? Uważam, że podświetlony fragment kodu nie tylko bardzo dobrze wyjaśnia faktyczne użycie, ale także demonstruje dalsze użycie, takie jak użycie „haka” związanego z Emacsem Lispem jako podzbiorem większego „haka” i tego, jak automatycznie utworzyć nazwy haka z istniejących głównych trybów z derived-mode-hook-name.
wasamasa
Lubię to bardziej niż moje, tylko dla (dolist ...)kontra (add-hook ...)<powtórzenie>. Będę trzymać tylko z kopalni przy zachowaniu Tryb określonych zmian oddzielny (plik-per-trybie use-package, el-get). Oba są rozwiązaniami typu „wszystko w jednym”, ale z różnych punktów widzenia.
Jonathan Leech-Pepin
Należy pamiętać, że jeśli nie podasz tutaj APPENDargumentu innego niż zero add-hook, wówczas hooki zostaną wywołane w odwrotnej kolejności od podanej przez ciebie kolejności list. Nic w tym złego; bądź tego świadomy, na wypadek, gdyby kolejność miała znaczenie.
Drew
5

Możesz dodać funkcję after-change-major-mode-hook, która sprawdza, czy nowy tryb jest interesujący (być może poprzez (not (derived-mode-p 'special-mode))), a jeśli tak, to czy działa non-special-mode-hook.

legoscia
źródło
Brzmi to całkiem fajnie (kiedy już odkryjesz wszystkie „niespecjalne” tryby, ponieważ jest kilka, które tylko używają fundamental-mode, ale robią więcej niż tylko wyświetlanie tekstu), ale trochę zbyt magicznie jak na mój gust. Stąd głosowanie.
wasamasa
4

Często zdarzało mi się, że @ sanityinc owija moje ustawienia i drobne aktywacje trybu w defun i zapętla się przez haki, aby to nazwać, ale chciałem czystszego podejścia, więc napisałem to makro:

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

Uwaga: jestem dash.elza czystością, ale można ją łatwo dostosować do użycia (dolist).

Następnie możesz zdefiniować zgrupowane tryby jako zmienne listy i używać ich w następujący sposób:

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

(hook-modes progish-modes
  (highlight-symbol-mode)
  (highlight-symbol-nav-mode))
waymondo
źródło
1
Zauważ, że tutaj możesz użyć, derived-mode-hook-nameaby uzyskać nazwę zmiennej przechwytującej trybu, unikając w ten sposób internsztuczki.
sanityinc
@sanityinc TIL derived-mode-hook-name. fajna wskazówka!
waymondo
1

Zamiast definiować nowy haczyk, który działa dla wszystkich trybów niepochodzących , możesz wykonać następujące czynności.

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

Nadal będziesz musiał dodać go do wszystkich trybów, ale definiując swoją funkcję tak, aby obejmowała wszystkie tryby, będziesz musiał zmienić tylko jedną definicję podczas dodawania / usuwania dodatkowych funkcji.

Jonathan Leech-Pepin
źródło
-2

Może możesz spróbować:

(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
źródło