aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoam Postavsky2017-12-14 21:25:13 -0500
committerNoam Postavsky2017-12-16 21:02:38 -0500
commit89cfdbf729bc731331358e0efc69547547aa3ca2 (patch)
treec70f4749d78bb754f604f100c361cb0668788793
parentc5061d81b972d9b846359d6b9be1c5a0fc4a2402 (diff)
downloademacs-89cfdbf729bc731331358e0efc69547547aa3ca2.tar.gz
emacs-89cfdbf729bc731331358e0efc69547547aa3ca2.zip
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.
-rw-r--r--lisp/elec-pair.el25
1 files changed, 22 insertions, 3 deletions
diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el
index 7f523d1df45..a980f51d3c0 100644
--- a/lisp/elec-pair.el
+++ b/lisp/elec-pair.el
@@ -24,6 +24,7 @@
24;;; Code: 24;;; Code:
25 25
26(require 'electric) 26(require 'electric)
27(eval-when-compile (require 'cl-lib))
27 28
28;;; Electric pairing. 29;;; Electric pairing.
29 30
@@ -222,6 +223,22 @@ inside a comment or string."
222 (electric-pair-mode nil)) 223 (electric-pair-mode nil))
223 (self-insert-command 1))) 224 (self-insert-command 1)))
224 225
226(cl-defmacro electric-pair--with-uncached-syntax ((table &optional start) &rest body)
227 "Like `with-syntax-table', but flush the syntax-ppss cache afterwards.
228Use this instead of (with-syntax-table TABLE BODY) when BODY
229contains code which may update the syntax-ppss cache. This
230includes calling `parse-partial-sexp' and any sexp-based movement
231functions when `parse-sexp-lookup-properties' is non-nil. The
232cache is flushed from position START, defaulting to point."
233 (declare (debug ((form &optional form) body)) (indent 1))
234 (let ((start-var (make-symbol "start")))
235 `(let ((syntax-propertize-function nil)
236 (,start-var ,(or start '(point))))
237 (unwind-protect
238 (with-syntax-table ,table
239 ,@body)
240 (syntax-ppss-flush-cache ,start-var)))))
241
225(defun electric-pair--syntax-ppss (&optional pos where) 242(defun electric-pair--syntax-ppss (&optional pos where)
226 "Like `syntax-ppss', but sometimes fallback to `parse-partial-sexp'. 243 "Like `syntax-ppss', but sometimes fallback to `parse-partial-sexp'.
227 244
@@ -240,7 +257,8 @@ when to fallback to `parse-partial-sexp'."
240 (skip-syntax-forward " >!") 257 (skip-syntax-forward " >!")
241 (point))))) 258 (point)))))
242 (if s-or-c-start 259 (if s-or-c-start
243 (with-syntax-table electric-pair-text-syntax-table 260 (electric-pair--with-uncached-syntax (electric-pair-text-syntax-table
261 s-or-c-start)
244 (parse-partial-sexp s-or-c-start pos)) 262 (parse-partial-sexp s-or-c-start pos))
245 ;; HACK! cc-mode apparently has some `syntax-ppss' bugs 263 ;; HACK! cc-mode apparently has some `syntax-ppss' bugs
246 (if (memq major-mode '(c-mode c++ mode)) 264 (if (memq major-mode '(c-mode c++ mode))
@@ -293,7 +311,8 @@ If point is not enclosed by any lists, return ((t) . (t))."
293 (cond ((< direction 0) 311 (cond ((< direction 0)
294 (condition-case nil 312 (condition-case nil
295 (eq (char-after pos) 313 (eq (char-after pos)
296 (with-syntax-table table 314 (electric-pair--with-uncached-syntax
315 (table)
297 (matching-paren 316 (matching-paren
298 (char-before 317 (char-before
299 (scan-sexps (point) 1))))) 318 (scan-sexps (point) 1)))))
@@ -323,7 +342,7 @@ If point is not enclosed by any lists, return ((t) . (t))."
323 (save-excursion 342 (save-excursion
324 (while (not outermost) 343 (while (not outermost)
325 (condition-case err 344 (condition-case err
326 (with-syntax-table table 345 (electric-pair--with-uncached-syntax (table)
327 (scan-sexps (point) (if (> direction 0) 346 (scan-sexps (point) (if (> direction 0)
328 (point-max) 347 (point-max)
329 (- (point-max)))) 348 (- (point-max))))