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?


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.


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.


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

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.


-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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.