Cómo definir pares de modos específicos adicionales para el modo de pares eléctricos

13

electric-pair-modees un modo integrado para insertar automáticamente pares coincidentes de delimitadores (paréntesis, corchetes, etc.) en función del modo principal actual.

Sé que puedo definir pares adicionales (que serán globales ) como este:

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

Mi pregunta es , ¿cómo puedo definir pares específicos de modo (por ejemplo //, ==para org-mode)?

itsjeyd
fuente

Respuestas:

7

Una forma sencilla de hacerlo es haciendo electric-pair-pairsy electric-pair-text-pairslocal al búfer y la personalización en ganchos para los modos pertinentes.

Ejemplo de trabajo para 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)

Tenga en cuenta que este enfoque es generalizable a otras situaciones en las que desea modificar el valor de una variable global para modos específicos.


Información adicional: setq-local

Desde la sección Creación y eliminación de enlaces locales de búfer del manual de Elisp :

Macro: setq-local variable value

Esta macro crea un enlace local de búfer en el búfer actual para VARIABLEy le da el valor local de búfer VALUE. Es equivalente a llamar make-local-variableseguido de setq. VARIABLEdebe ser un símbolo sin comillas.

itsjeyd
fuente
7

La forma correcta: llenar un informe de error a través del canal apropiado de su proyecto, por ejemplo org-submit-bug-report, o report-emacs-bugy argumentar por qué la clase sintaxis de su personaje favorito debe ser cambiado.

Alternativamente, puede modificar la tabla de sintaxis adecuada,, (info "(elisp) Syntax Tables")en su init.el.

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

Alternativamente, puede usar las variables de reserva. Aquí hay un defun que debería funcionar, pero que es posible que desee hacer más bonito:

(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
fuente
Gracias por publicar una respuesta que muestra cómo modificar la tabla de sintaxis. De las dos sugerencias en su respuesta, este es el enfoque que preferiría. W / r / t usando las variables de reserva, se me ocurrió otra solución que es un poco más corta que la defunde su respuesta.
itsjeyd
2

Esta respuesta no responde a su pregunta sobre cómo configurar electric-pair-mode. Pero puede llevarlo a los resultados que desea.

El wrap-regionpaquete disponible en Melpa podría ser la respuesta a su problema. Aquí está su breve descripción de su github:

Wrap Region es un modo menor para Emacs que envuelve una región con signos de puntuación. Para los modos de marcado "etiquetados", como HTML y XML, se ajusta con etiquetas.

Así es como lo configuré para que funcione en mis modos seleccionados. El fragmento también cubre los puntos que planteó en su pregunta; sobre org-modemarcadores de propiedad de fuente.

(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

Me gustaría agregar que este paquete funciona muy bien con el expand-regionpaquete (también disponible en Melpa).

Con estos 2 paquetes, cuando estoy dentro org-mode, haciendo: MY-EXPAND-REGION-BINDING *en una palabra, se pondrá en negrita.

Kaushal Modi
fuente
Gracias por tu respuesta. Estaba al tanto del wrap-regionpaquete; Es bastante útil. Actualmente estoy tratando de reducir la cantidad de paquetes de terceros de los que dependen, por lo que no utilizaré esta solución, ¡pero definitivamente merece una mención aquí! :)
itsjeyd
2

Sobre la base de la respuesta 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
fuente
Tuve que escapar de los personajes para que funcione(?\= . ?\=)
phoxd