如何为电对模式定义其他特定于模式的对


13

electric-pair-mode是一种内置模式,用于根据当前的主模式自动插入匹配的定界符对(括号,方括号等)。

我知道我可以像这样定义其他对(将是global):

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

我的问题是,如何定义特定于模式的对(例如//==for org-mode)?

Answers:


7

一个简单的方法来做到这一点是通过使electric-pair-pairselectric-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

Elisp手册的“ 创建和删除缓冲区-本地绑定”部分中:

巨集: setq-local variable value

此宏在当前缓冲区中为创建一个本地缓冲区绑定VARIABLE,并为其提供本地缓冲区值VALUE。这等同于调用make-local-variable之后setqVARIABLE应该是未加引号的符号。


7

正确的方法:通过项目的适当渠道填写错误报告,例如org-submit-bug-reportreport-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,但是您可能想更漂亮:

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

感谢您发布答案,该答案显示了如何修改语法表。在您回答的两个建议中,这是我更喜欢的方法。W / r / t使用后备变量,我想出了另一种解决方案,该解决方案defun您的答案中的短一些。
itsjeyd 2014年

2

这个答案不会回答您有关如何配置的问题electric-pair-mode。但这可能会导致您获得想要的结果。

wrap-regionMelpa上可用的软件包可能是您解决问题的答案。这是来自其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上找到)。

使用这2个程序包,当我在时org-mode,做MY-EXPAND-REGION-BINDING *一个单词会使它大胆。


感谢您的回答。我知道这个wrap-region包裹;这很有用。我目前正在尝试减少我依赖的第三方软件包的数量,因此我不会使用此解决方案,但是在这里绝对值得一提!:)
itsjeyd 2014年

2

基于其jeyd的答案:

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

为了使它工作,我不得不转义字符(?\= . ?\=)
phoxd
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.