rust-lang / rust-mode

Emacs configuration for Rust
Apache License 2.0
1.1k stars 176 forks source link

[PR] Add `single quotes` into electric-pair-pairs for emacs version>24.1 to make it can be autopaired #402

Open zw963 opened 3 years ago

zw963 commented 3 years ago

This variable it original value is:

((?\" . ?\")
    (,(nth 0 electric-quote-chars) . ,(nth 1 electric-quote-chars))
    (,(nth 2 electric-quote-chars) . ,(nth 3 electric-quote-chars)))

So, when we do coding on rust-mode, when we typing double quotes ", it can be autopaired into "|" (| is cursor) But, single quote can't.

After add following code into rust-mode-hook

(add-to-list (make-local-variable 'electric-pair-pairs) '(?' . ?'))

Now, when we typing '|, it can be autopaired into '|' now, and not take effect others mode. e.g. emacs-lisp-mode

Thank you.

zw963 commented 3 years ago

Because ' is used by lifetime parameter, so, maybe this is not a good idea. sorry.

zw963 commented 3 years ago

Following is a working solution for:

single quote autopair only valid unless a & is ahead of single quote.

(defvar electric-pair-inhibit-predicate-mode-chars-alist
  '((t . nil))
  "A list of major-mode and inhibit chars.

Each element is in the form of (MODE . (CHAR/CHAR-STRING/CHAR-FUNCTION ...)).

MODE
    A mode, or t for all modes.

CHAR
    A character to match the input. for example:

        ?\{

CHAR-STRING
    A pair of character and string, the character to match the input,
    the string for ‘looking-back’. for example:

        (?\{ . \":{\")

CHAR-FUNCTION
    A pair of character and function, the character to match the input,
    the function accept the input character as parameter. for example:

        (?\{ . (lambda (_c)
                 (eq ?: (char-before (1- (point))))))")

(defun electric-pair-inhibit-predicate-function (c)
  (let ((alist
         (append
          (assoc-default major-mode electric-pair-inhibit-predicate-mode-chars-alist)
          (assoc-default t          electric-pair-inhibit-predicate-mode-chars-alist))))
    (or (cl-member c
                   alist
                   :test
                   (lambda (c it)
                     (cond
                      ((characterp it) (equal c it))
                      ((and (consp it) (equal c (car it)))
                       (cond ((stringp   (cdr it)) (looking-back (cdr it) 1))
                             ((functionp (cdr it)) (funcall (cdr it) c)))))))
        (electric-pair-default-inhibit c))))

(with-eval-after-load 'elec-pair
  (setq electric-pair-inhibit-predicate
        #'electric-pair-inhibit-predicate-function))

(add-to-list 'electric-pair-inhibit-predicate-mode-chars-alist
             '(rust-mode . ((?' . "&'"))))

(add-hook 'rust-mode-hook
          #'(lambda ()
              (modify-syntax-entry ?' "\"" rust-mode-syntax-table)
              ))