Як визначити додаткові пари, характерні для режиму для електричного парного режиму


13

electric-pair-modeце вбудований режим для автоматичного вставки збіжних пар роздільників (круглі дужки, квадратні дужки тощо) на основі поточного основного режиму.

Я знаю, що можу визначити додаткові пари (які будуть глобальними ) на зразок цього:

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

Моє запитання полягає в тому , як я можу визначити певні для режиму пари (наприклад //, ==для org-mode)?

Відповіді:


7

Самий простий спосіб зробити це шляхом створення electric-pair-pairsі electric-pair-text-pairsбуфер локального і налаштовуючи їх гачками для відповідних режимів.

Приклад роботи для 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)

Зауважте, що цей підхід узагальнюється для інших ситуацій, в яких потрібно змінити значення глобальної змінної для конкретних режимів.


Додаткова інформація: setq-local

З Створення та видалення буфера-Local Прив'язка секції ручної Elisp :

Макрос: setq-local variable value

Цей макрос створює локальне зв'язування буфера в поточному буфері для VARIABLEта надає йому значення локального буфера VALUE. Це еквівалентно дзвінку, make-local-variableза яким слід setq. VARIABLEповинен бути символом без котирування.


7

Правильний спосіб: заповніть звіт про помилку через відповідний канал вашого проекту, наприклад, org-submit-bug-reportабо report-emacs-bugта аргументуйте, чому слід змінити клас синтаксису улюбленого персонажа.

Крім того, ви можете змінити відповідну таблицю синтаксису (info "(elisp) Syntax Tables")у вашому init.el.

Спробуємо 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))

Крім того, ви можете використовувати резервні змінні. Ось дефініція, яка має спрацювати, але яку ви можете зробити красивішою:

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

Дякуємо, що опублікували відповідь, яка показує, як змінити таблицю синтаксису. З двох пропозицій у вашій відповіді я вважаю за краще такий підхід. З / п / т, використовуючи резервні змінні, я придумав інше рішення, яке трохи коротше, ніж defunу вашій відповіді.
itsjeyd

2

Ця відповідь не відповідає на ваше запитання щодо налаштування electric-pair-mode. Але це може призвести до бажаних результатів.

wrap-regionПакет , доступний на Melpa може бути відповідь на вашу проблему. Ось його короткий опис з його github:

Область обертання - це незначний режим для Emacs, який обгортає область з розділовими знаками. Для режимів розмітки "теги", таких як HTML та XML, вона обгортається тегами.

Ось як я налаштував його працювати в вибраних режимах. Фрагмент також охоплює точки, які ви порушили у своєму запитанні; про org-modeмаркери властивостей шрифту.

(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

Я хотів би додати, що цей пакет дуже добре працює з expand-regionпакетом (також доступний на Melpa).

З цими двома пакетами, коли я перебуваю org-mode, роблю: MY-EXPAND-REGION-BINDING *на слові, це зробить сміливим.


Дякую за вашу відповідь. Мені було відомо про wrap-regionпакет; це досить корисно. Наразі я намагаюся зменшити кількість сторонніх пакетів, від яких я залежу, тому я не буду використовувати це рішення, але воно, безумовно, заслуговує на згадку тут! :)
itsjeyd

2

Спираючись на відповідь іцдейда:

(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 '((?` . ?')))

Мені довелося бігти персонажів, щоб змусити його працювати(?\= . ?\=)
фокс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.