Comment «grouper» les crochets?

14

Il y a certaines choses comme l'affichage des espaces de fin, l'affichage des limites de tampon, les délimiteurs de couleur arc-en-ciel et bien d'autres que j'aimerais activer dans la plupart des modes ou plutôt, tous ceux liés à la programmation et au texte (car l'affichage des espaces de fin dans, disons ediff-mode, serait en conflit avec le mode majeur) au lieu d'utiliser un mode mineur globalisé avec des règles d'exception. Étant donné que la plupart des modes sont dérivés de prog-modeou text-mode, l'ajout de la fonction en question aux deux prog-mode-hooket text-mode-hookfonctionne, cependant, il existe suffisamment de modes ne suivant pas cette spécification, tels que css-modeou LaTeX-mode.

Je voudrais définir un hook qui englobe tous ces modes pour le moment pour n'ajouter des fonctions qu'à un seul hook. Appelons cela non-special-mode-hook(pour le distinguer special-mode-hook). Comment pourrais-je créer un tel crochet exécuté pour tous les principaux modes pour lesquels il est conçu?

wasamasa
la source

Réponses:

19

Il vous suffit de regrouper ces paramètres dans une fonction et d'ajouter cette fonction à toutes les fonctions de raccordement pertinentes:

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

Aucune autre façon de le faire ne serait plus concise: quoi qu'il arrive, quelque part vous aurez une liste blanche ou une liste noire de modes. Dans la pratique, vous ne trouverez que quelques modes qui doivent être ajoutés à la liste, je suggère donc de garder les choses simples.

Dans ma propre configuration, j'utilise exactement cette astuce pour unifier la configuration de plusieurs modes orientés lisp.

sanityinc
la source
Merci, je pense que j'adapterai cette solution pour d'autres groupes utiles (tels que les groupes lispy), aussi.
wasamasa
1
C'est exactement ce que je fais moi-même: github.com/purcell/emacs.d/blob/…
sanityinc
1
Excellent, pourriez-vous peut-être ajouter l'URL à votre réponse? Je pense que l'extrait en surbrillance explique non seulement très bien l'utilisation réelle, mais démontre également une utilisation supplémentaire, comme l'utilisation d'un "hook" lié à Emacs Lisp comme sous-ensemble d'un plus grand "hook" et comment on créerait automatiquement des noms de hook à partir de modes principaux existants avec derived-mode-hook-name.
wasamasa
J'aime plus que le mien, juste pour le (dolist ...)vs (add-hook ...)<repeat>. Je ne bâton avec moi en gardant le mode spécifique change séparé (fichier par mode use-package, el-get). Les deux sont des solutions tout-en-un, mais d'un point de vue différent.
Jonathan Leech-Pepin
Sachez que si vous ne fournissez pas d' APPENDargument non nul add-hookici, les hooks seront invoqués dans l'ordre inverse de l'ordre de liste que vous fournissez. Aucun problème avec ça; sachez-le, au cas où la commande serait importante.
Tiré le
5

Vous pouvez ajouter une fonction à after-change-major-mode-hook, qui vérifie si le nouveau mode est intéressant (éventuellement via (not (derived-mode-p 'special-mode))), et si c'est le cas, s'exécute non-special-mode-hook.

legoscia
la source
Cela semble assez astucieux (une fois que l'on a compris tous les modes "non spéciaux" car il y en a quelques-uns qui utilisent simplement fundamental-mode, mais font plus que simplement afficher du texte), mais un peu trop magique à mon goût. D'où le vote positif.
wasamasa
4

Je me suis retrouvé à faire souvent le schéma de @ sanityinc pour encapsuler mes paramètres et activations de mode mineur dans un defun et boucler à travers des crochets pour l'appeler, mais je voulais une approche plus propre, j'ai donc écrit cette macro:

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

Remarque: je suis dash.elpour la propreté mais il pourrait facilement être adapté à l'utilisation (dolist).

Ensuite, vous pouvez définir des modes groupés en tant que variables de liste et les utiliser comme suit:

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

(hook-modes progish-modes
  (highlight-symbol-mode)
  (highlight-symbol-nav-mode))
waymondo
la source
1
Notez qu'ici, vous pouvez utiliser derived-mode-hook-namepour obtenir le nom de la variable hook d'un mode, évitant ainsi l' internastuce.
sanityinc du
@sanityinc TIL derived-mode-hook-name. bon conseil!
waymondo
1

Plutôt que de définir un nouveau hook qui fonctionne pour tous ces modes non dérivés , vous pouvez procéder comme suit.

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

Vous devrez toujours l'ajouter à tous les modes, mais en définissant votre fonction pour inclure tous les modes, vous n'aurez qu'à modifier une définition lors de l'ajout / suppression de fonctionnalités supplémentaires.

Jonathan Leech-Pepin
la source
-2

Vous pouvez peut-être essayer ceci:

(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
la source