From 5b3f0dfb1673617e4646be2be0874b168acc46c4 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 14 Dec 2017 21:25:13 -0500 Subject: [PATCH v1] 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. --- lisp/elec-pair.el | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el index 7f523d1df4..bdf4bd14b5 100644 --- a/lisp/elec-pair.el +++ b/lisp/elec-pair.el @@ -24,6 +24,7 @@ ;;; Code: (require 'electric) +(eval-when-compile (require 'cl-lib)) ;;; Electric pairing. @@ -222,6 +223,18 @@ electric-pair--insert (electric-pair-mode nil)) (self-insert-command 1))) +(cl-defmacro electric-pair--with-uncached-syntax ((table &optional start-scan) &rest body) + "Like `with-syntax-table', but flush the syntax-ppss cache after." + ;; See Bug#29710 and Bug#23443. + (declare (debug ((form &optional form) body)) (indent 1)) + (let ((start-scan-var (make-symbol "start-scan"))) + `(let ((syntax-propertize-function nil) + (,start-scan-var ,(or start-scan '(point)))) + (unwind-protect + (with-syntax-table ,table + ,@body) + (syntax-ppss-flush-cache ,start-scan-var))))) + (defun electric-pair--syntax-ppss (&optional pos where) "Like `syntax-ppss', but sometimes fallback to `parse-partial-sexp'. @@ -240,7 +253,8 @@ electric-pair--syntax-ppss (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 +307,8 @@ electric-pair--balance-info (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 +338,7 @@ electric-pair--balance-info (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)))) -- 2.11.0