Come definire ulteriori coppie specifiche della modalità per la modalità coppia elettrica


13

electric-pair-modeè una modalità integrata per l'inserimento automatico di coppie corrispondenti di delimitatori (parentesi, parentesi quadre, ecc.) in base alla modalità principale corrente.

So che posso definire coppie aggiuntive (che saranno globali ) in questo modo:

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

La mia domanda è : come posso definire le coppie specifiche della modalità (ad es. //, ==Per org-mode)?

Risposte:


7

Un modo semplice per farlo è creare electric-pair-pairse electric-pair-text-pairsbufferare localmente e personalizzarli in hook per le modalità pertinenti.

Esempio di lavoro per 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)

Si noti che questo approccio è generalizzabile ad altre situazioni in cui si desidera modificare il valore di una variabile globale per modalità specifiche.


Informazioni addizionali: setq-local

Dalla sezione Creazione ed eliminazione di bind buffer-locali del manuale Elisp :

macro: setq-local variable value

Questa macro crea un'associazione buffer-local nel buffer corrente per VARIABLEe gli fornisce il valore buffer-local VALUE. È equivalente alla chiamata make-local-variableseguita da setq. VARIABLEdovrebbe essere un simbolo non quotato.


7

Il modo corretto: riempi una segnalazione di bug attraverso il canale appropriato del tuo progetto, ad esempio org-submit-bug-reporto report-emacs-buge spiega perché la classe di sintassi del tuo personaggio preferito dovrebbe essere cambiata.

In alternativa, è possibile modificare la tabella di sintassi corretta (info "(elisp) Syntax Tables"), nel proprio init.el.

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

In alternativa, è possibile utilizzare le variabili di fallback. Ecco un defun che dovrebbe funzionare, ma che potresti voler rendere più bello:

(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
               '("/" "=" ("`" . "'"))))))

Grazie per aver pubblicato una risposta che mostra come modificare la tabella della sintassi. Tra i due suggerimenti nella tua risposta, questo è l'approccio che preferirei. Usando le variabili di fallback, ho trovato un'altra soluzione un po 'più corta della defunrisposta.
itsjeyd

2

Questa risposta non risponde alla tua domanda su come configurare electric-pair-mode. Ma potrebbe portarti ai risultati desiderati.

Il wrap-regionpacchetto disponibile su Melpa potrebbe essere la risposta al tuo problema. Ecco la sua breve descrizione dal suo github:

Wrap Region è una modalità minore per Emacs che avvolge una regione con punteggiatura. Per le modalità di markup "taggate", come HTML e XML, si avvolge con i tag.

Ecco come l'ho impostato per funzionare nelle mie modalità selezionate. Lo snippet copre anche i punti sollevati nella tua domanda; sui org-modemarcatori delle proprietà dei caratteri.

(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

Vorrei aggiungere che questo pacchetto funziona davvero bene con il expand-regionpacchetto (disponibile anche su Melpa).

Con questi 2 pacchetti, quando ci sto org-mode, facendo: MY-EXPAND-REGION-BINDING *su una parola lo renderà audace.


Grazie per la tua risposta. Ero a conoscenza del wrap-regionpacchetto; è abbastanza utile. Attualmente sto cercando di ridurre il numero di pacchetti di terze parti da cui dipendo, quindi non userò questa soluzione, ma merita sicuramente una menzione qui! :)
itsjeyd

2

Basandoci sulla risposta di 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 '((?` . ?')))

Ho dovuto sfuggire ai personaggi per farlo funzionare(?\= . ?\=)
phoxd,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.