mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-08 15:35:02 +00:00
Don't mess up syntax-ppss cache in electric-pair (Bug#29710)
In Emacs 25 and above, calling `scan-sexps', `parse-partial-sexp', or similar may update the syntax-ppss cache if `parse-sexp-lookup-properties' is non-nil. Therefore, when calling any of these functions with a different than normal syntax-table, the cache must be cleaned afterwards. * lisp/elec-pair.el (electric-pair--with-uncached-syntax): New macro. (electric-pair--syntax-ppss, electric-pair--balance-info): Use it.
This commit is contained in:
parent
c5061d81b9
commit
89cfdbf729
@ -24,6 +24,7 @@
|
||||
;;; Code:
|
||||
|
||||
(require 'electric)
|
||||
(eval-when-compile (require 'cl-lib))
|
||||
|
||||
;;; Electric pairing.
|
||||
|
||||
@ -222,6 +223,22 @@ inside a comment or string."
|
||||
(electric-pair-mode nil))
|
||||
(self-insert-command 1)))
|
||||
|
||||
(cl-defmacro electric-pair--with-uncached-syntax ((table &optional start) &rest body)
|
||||
"Like `with-syntax-table', but flush the syntax-ppss cache afterwards.
|
||||
Use this instead of (with-syntax-table TABLE BODY) when BODY
|
||||
contains code which may update the syntax-ppss cache. This
|
||||
includes calling `parse-partial-sexp' and any sexp-based movement
|
||||
functions when `parse-sexp-lookup-properties' is non-nil. The
|
||||
cache is flushed from position START, defaulting to point."
|
||||
(declare (debug ((form &optional form) body)) (indent 1))
|
||||
(let ((start-var (make-symbol "start")))
|
||||
`(let ((syntax-propertize-function nil)
|
||||
(,start-var ,(or start '(point))))
|
||||
(unwind-protect
|
||||
(with-syntax-table ,table
|
||||
,@body)
|
||||
(syntax-ppss-flush-cache ,start-var)))))
|
||||
|
||||
(defun electric-pair--syntax-ppss (&optional pos where)
|
||||
"Like `syntax-ppss', but sometimes fallback to `parse-partial-sexp'.
|
||||
|
||||
@ -240,7 +257,8 @@ when to fallback to `parse-partial-sexp'."
|
||||
(skip-syntax-forward " >!")
|
||||
(point)))))
|
||||
(if s-or-c-start
|
||||
(with-syntax-table electric-pair-text-syntax-table
|
||||
(electric-pair--with-uncached-syntax (electric-pair-text-syntax-table
|
||||
s-or-c-start)
|
||||
(parse-partial-sexp s-or-c-start pos))
|
||||
;; HACK! cc-mode apparently has some `syntax-ppss' bugs
|
||||
(if (memq major-mode '(c-mode c++ mode))
|
||||
@ -293,7 +311,8 @@ If point is not enclosed by any lists, return ((t) . (t))."
|
||||
(cond ((< direction 0)
|
||||
(condition-case nil
|
||||
(eq (char-after pos)
|
||||
(with-syntax-table table
|
||||
(electric-pair--with-uncached-syntax
|
||||
(table)
|
||||
(matching-paren
|
||||
(char-before
|
||||
(scan-sexps (point) 1)))))
|
||||
@ -323,7 +342,7 @@ If point is not enclosed by any lists, return ((t) . (t))."
|
||||
(save-excursion
|
||||
(while (not outermost)
|
||||
(condition-case err
|
||||
(with-syntax-table table
|
||||
(electric-pair--with-uncached-syntax (table)
|
||||
(scan-sexps (point) (if (> direction 0)
|
||||
(point-max)
|
||||
(- (point-max))))
|
||||
|
Loading…
Reference in New Issue
Block a user