Comment définir des paires supplémentaires spécifiques au mode pour le mode paire électrique

13

electric-pair-modeest un mode intégré pour insérer automatiquement des paires de délimiteurs correspondantes (parenthèses, crochets, etc.) en fonction du mode principal actuel.

Je sais que je peux définir des paires supplémentaires (qui seront globales ) comme ceci:

(push '(?\' . ?\') electric-pair-pairs)      ; Automatically pair single-quotes
(push '(?\' . ?\') electric-pair-text-pairs) ; ... in comments

Ma question est , comment puis-je définir des paires spécifiques au mode (par exemple //, ==pour org-mode)?

itsjeyd
la source

Réponses:

7

Un moyen facile de le faire est en faisant electric-pair-pairset electric-pair-text-pairstampon local et de les personnaliser en crochets pour les modes pertinents.

Exemple de travail pour org-mode:

(defvar org-electric-pairs '((?/ . ?/) (?= . ?=)) "Electric pairs for org-mode.")

(defun org-add-electric-pairs ()
  (setq-local electric-pair-pairs (append electric-pair-pairs org-electric-pairs))
  (setq-local electric-pair-text-pairs electric-pair-pairs))

(add-hook 'org-mode-hook 'org-add-electric-pairs)

Notez que cette approche est généralisable à d'autres situations dans lesquelles vous souhaitez modifier la valeur d'une variable globale pour des modes spécifiques.


Information additionnelle: setq-local

Dans la section Création et suppression de liaisons de tampon local du manuel Elisp :

Macro: setq-local variable value

Cette macro crée une liaison tampon-locale dans le tampon actuel pour VARIABLE, et lui donne la valeur tampon-locale VALUE. Cela équivaut à appeler make-local-variablesuivi de setq. VARIABLEdevrait être un symbole sans guillemets.

itsjeyd
la source
7

La bonne façon: remplissez un rapport de bogue via le canal approprié de votre projet, par exemple org-submit-bug-reportou report-emacs-buget discutez pourquoi la classe de syntaxe de votre personnage préféré devrait être modifiée.

Alternativement, vous pouvez modifier la table de syntaxe appropriée (info "(elisp) Syntax Tables"), dans votre init.el.

Essayons Org:

(with-eval-after-load 'org
  (modify-syntax-entry ?/ "(/" org-mode-syntax-table)
  (modify-syntax-entry ?= "(=" org-mode-syntax-table)
  (add-hook 'org-mode-hook 'electric-pair-mode))

Vous pouvez également utiliser les variables de secours. Voici un defun qui devrait fonctionner, mais que vous voudrez peut-être rendre plus joli:

(defun rasmus/electric-pairs-with-local-pairs (pairs)
  "Start electric pair with buffer-local PAIRS.

  PAIRS is a list of strings and/or cons of strings."
  (require 'elec-pair)
  (let ((ec-lists '(electric-pair-pairs electric-pair-text-pairs)))
    (mapc 'make-local-variable ec-lists)        
    (mapc (lambda (L)
            (mapc (lambda (elm) (add-to-list L elm))
                  (mapcar (lambda (x)
                            (if (consp x)
                                (cons (string-to-char (car x))
                                      (string-to-char (cdr x)))
                              (cons (string-to-char x)
                                    (string-to-char x))))
                          pairs)))
          ec-lists))
  (electric-pair-mode t))

(with-eval-after-load 'org
  (add-hook 'org-mode-hook
            (lambda ()
              (rasmus/electric-pairs-with-local-pairs
               '("/" "=" ("`" . "'"))))))
rasmus
la source
Merci d'avoir publié une réponse qui montre comment modifier la table de syntaxe. Parmi les deux suggestions de votre réponse, c'est l'approche que je préférerais. W / r / t utilisant les variables de secours, j'ai trouvé une autre solution qui est un peu plus courte que defundans votre réponse.
itsjeyd
2

Cette réponse ne répond pas à votre question sur la configuration electric-pair-mode. Mais cela pourrait vous conduire aux résultats souhaités.

Le wrap-regionpackage disponible sur Melpa pourrait être la réponse à votre problème. Voici sa brève description de son github:

Wrap Region est un mode mineur pour Emacs qui enveloppe une région avec des ponctuations. Pour les modes de balisage «balisés», tels que HTML et XML, il encapsule des balises.

Voici comment je l'ai configuré pour fonctionner dans mes modes sélectionnés. L'extrait couvre également les points que vous avez soulevés dans votre question; sur org-modeles marqueurs de propriété de police.

(require 'wrap-region)

;; Enable wrap-region in the following major modes
(dolist (hook '(emacs-lisp-mode-hook
                org-mode-hook))
  (add-hook hook 'wrap-region-mode))

(wrap-region-add-wrapper "`" "'") ; select region, hit ` then region -> `region'

(wrap-region-add-wrapper "=" "=" nil 'org-mode) ; select region, hit = then region -> =region= in org-mode
(wrap-region-add-wrapper "*" "*" nil 'org-mode) ; select region, hit * then region -> *region* in org-mode
(wrap-region-add-wrapper "/" "/" nil 'org-mode) ; select region, hit / then region -> /region/ in org-mode
(wrap-region-add-wrapper "_" "_" nil 'org-mode) ; select region, hit _ then region -> _region_ in org-mode
(wrap-region-add-wrapper "+" "+" nil 'org-mode))) ; select region, hit + then region -> +region+ in org-mode

Je voudrais ajouter que ce package fonctionne très bien avec le expand-regionpackage (également disponible sur Melpa).

Avec ces 2 packages, quand j'y suis org-mode, faire: MY-EXPAND-REGION-BINDING *sur un mot le rendra gras.

Kaushal Modi
la source
Merci pour votre réponse. J'étais au courant du wrap-regionpaquet; c'est assez utile. J'essaie actuellement de réduire le nombre de packages tiers dont je dépend, donc je n'utiliserai pas cette solution, mais elle mérite certainement une mention ici! :)
itsjeyd
2

S'appuyant sur la réponse de itsjeyd:

(defmacro spw/add-mode-pairs (hook pairs)
  `(add-hook ,hook
             (lambda ()
               (setq-local electric-pair-pairs (append electric-pair-pairs ,pairs))
               (setq-local electric-pair-text-pairs electric-pair-pairs))))

(spw/add-mode-pairs 'emacs-lisp-mode-hook '((?` . ?')))
Sean Whitton
la source
J'ai dû échapper à des personnages pour le faire fonctionner(?\= . ?\=)
phoxd