[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#29710: Emacs becomes unresponsive when typing brackets (haskell-mode
From: |
Noam Postavsky |
Subject: |
bug#29710: Emacs becomes unresponsive when typing brackets (haskell-mode) |
Date: |
Thu, 14 Dec 2017 21:31:20 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.0.90 (gnu/linux) |
tags 29710 + patch
quit
Noam Postavsky <npostavs@users.sourceforge.net> writes:
> I can reproduce also in 25.3, not in 24.5. Probably same issue as
> Bug#23443, i.e., electric-pair-mode needs to clear the cache after it
> finishes messing with the syntax table.
Here's a patch:
>From 5b3f0dfb1673617e4646be2be0874b168acc46c4 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
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