[已解决] Emacs 27, rust-mode, 如何让单引号自动的 autopair, 但是,单引号前面如果是 & 则例外。

初步判断存在以下问题:

  1. rust-mode.el 有设置自己的 inhibit 函数,抢走了执行权:
(setq-local electric-pair-inhibit-predicate 'rust-electric-pair-inhibit-predicate-wrap)
  1. 不应该设置 electric-pair-pairs,它的优先级高于 inhibit 函数,等于是强制插入配对字符。应该采用 modify-syntax-entry 来定义成对符号。

html-mode 为例:

(with-temp-buffer
  (html-mode)
  (electric-pair-syntax-info ?<))
;; => (40 62 nil nil)
;;      | |   |
;;      | |   '-- 为 nil 表示将执行 inhibit 函数。
;;      | |       如果用 electric-pair-pairs 设置配对符号,
;;      | |       则必返回 t,表示无需后续判断,强制插入配对符号。
;;      | '------ 配对的右侧符号 ?>。
;;      '-------- 40 说明当前插入的是成对符号的左侧。

试试以下配置:

(defun rust/electric-pair-inhibit-predicate (c)
  (let ((al (assoc major-mode electric-pair-inhibit-predicate-mode-chars-alist)))
    (if (assoc c (cdr al))
        (electric-pair-inhibit-predicate-function c)
      (rust-electric-pair-inhibit-predicate-wrap c))))

(with-eval-after-load 'rust-mode
  (modify-syntax-entry ?' "\"" rust-mode-syntax-table)
  (add-to-list 'electric-pair-inhibit-predicate-mode-chars-alist
               '(rust-mode . ((?' . "&'"))))
  (add-hook 'rust-mode-hook
            (lambda ()
              (setq-local electric-pair-inhibit-predicate
                          #'rust/electric-pair-inhibit-predicate))))
2 个赞