Cara menetapkan pasangan mode khusus tambahan untuk mode pasangan listrik

13

electric-pair-modeadalah built-in modus untuk secara otomatis memasukkan pasangan yang cocok pembatas (kurung, tanda kurung, dll) berdasarkan mode utama saat ini.

Saya tahu bahwa saya dapat menentukan pasangan tambahan (yang akan mendunia ) seperti ini:

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

Pertanyaan saya adalah , bagaimana saya bisa mendefinisikan pasangan mode-spesifik (misalnya //,, ==untuk org-mode)?

itu hanya
sumber

Jawaban:

7

Cara mudah untuk melakukan ini adalah dengan membuat electric-pair-pairsdan electric-pair-text-pairsbuffer-lokal dan menyesuaikan mereka dalam kaitan untuk mode yang relevan.

Contoh kerja untuk 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)

Perhatikan bahwa pendekatan ini dapat digeneralisasikan untuk situasi lain di mana Anda ingin memodifikasi nilai variabel global untuk mode tertentu.


Informasi tambahan: setq-local

Dari bagian Binding Membuat dan Menghapus Buffer-Lokal dari manual Elisp :

Makro: setq-local variable value

Makro ini membuat buffer-local binding di buffer saat ini untuk VARIABLE, dan memberinya nilai buffer-local VALUE. Ini sama dengan panggilan make-local-variablediikuti oleh setq. VARIABLEharus menjadi simbol yang tidak dikutip.

itu hanya
sumber
7

Cara yang benar: isi laporan bug melalui saluran yang tepat dari proyek Anda, misalnya org-submit-bug-reportatau report-emacs-bugdan berdebat mengapa kelas sintaks karakter favorit Anda harus diubah.

Atau, Anda bisa memodifikasi tabel sintaks yang tepat (info "(elisp) Syntax Tables"), di init.el.

Ayo coba 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))

Atau, Anda bisa menggunakan variabel fallback. Berikut ini defun yang seharusnya berfungsi, tetapi Anda mungkin ingin membuatnya lebih cantik:

(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
sumber
Terima kasih telah mengirim jawaban yang menunjukkan cara memodifikasi tabel sintaks. Dari dua saran dalam jawaban Anda, inilah pendekatan yang saya inginkan. W / r / t menggunakan variabel fallback, saya datang dengan solusi lain yang sedikit lebih pendek daripada defunjawaban Anda.
itsjeyd
2

Jawaban ini tidak menjawab pertanyaan Anda tentang cara mengonfigurasi electric-pair-mode. Tapi itu mungkin membawa Anda ke hasil yang Anda inginkan.

The wrap-regionpaket yang tersedia pada Melpa mungkin menjadi jawaban untuk masalah Anda. Berikut ini deskripsi singkatnya dari github-nya:

Wrap Region adalah mode minor untuk Emacs yang membungkus suatu wilayah dengan tanda baca. Untuk mode markup "tag", seperti HTML dan XML, mode ini dibungkus dengan tag.

Inilah cara saya mengaturnya agar berfungsi dalam mode yang saya pilih. Cuplikan juga membahas poin-poin yang Anda ajukan dalam pertanyaan Anda; tentang org-modepenanda properti font.

(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

Saya ingin menambahkan bahwa paket ini berfungsi sangat baik dengan expand-regionpaket tersebut (juga tersedia di Melpa).

Dengan 2 paket ini, ketika saya masuk org-mode, melakukan: MY-EXPAND-REGION-BINDING *pada sebuah kata akan membuatnya berani.

Kaushal Modi
sumber
Terima kasih atas jawaban anda. Saya mengetahui wrap-regionpaket itu; ini cukup berguna. Saat ini saya mencoba untuk mengurangi jumlah paket pihak ketiga yang saya andalkan, jadi saya tidak akan menggunakan solusi ini, tetapi pasti layak disebutkan di sini! :)
itsjeyd
2

Membangun dari jawaban jayd:

(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
sumber
Saya harus melarikan diri karakter untuk membuatnya berfungsi(?\= . ?\=)
phoxd