unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Allen Li <darkfeline@felesatra.moe>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: Lars Ingebrigtsen <larsi@gnus.org>,
	49629@debbugs.gnu.org, Noam Postavsky <npostavs@gmail.com>
Subject: bug#49629: 27.2; electric-pair-mode doesn't work for angle brackets in HTML file
Date: Sat, 2 Jul 2022 03:48:31 -0700	[thread overview]
Message-ID: <CADbSrJxwDGJAxbQreYVTrf3xdyH4TSEKKbiHKAu6c2KJC=EBMQ@mail.gmail.com> (raw)
In-Reply-To: <jwvilom707b.fsf-monnier+emacs@gnu.org>


[-- Attachment #1.1: Type: text/plain, Size: 1253 bytes --]

How does the attached patch look?

I did not clear the syntax patch for the entire buffer because I was
worried of the performance impact.
We assume that we won't be touching the part of the buffer before the
specified start.
IIUC there is no issue keeping the cached state from before start using the
original table,
as we only want to consider the text succeeding start as text.

On Mon, Jun 27, 2022 at 5:39 AM Stefan Monnier <monnier@iro.umontreal.ca>
wrote:

> > FIrst, changing `syntax-propertize-function` from nil to `ignore` was
> wrong
> > IIUC.  If the function is set, then it is wholly responsible for applying
> > syntax table.  When set to nil the default behavior is used, but when set
> > to `ignore`, that should mean that no syntax is applied at all.  In
> > practice, I don't know what behavior that causes.
>
> The two behave identically (IOW the "default behavior" is the same as
> that of `ignore`).
>
> > Second, since `electric-pair--with-uncached-syntax` appears to be used
> for
> > doing text-mode matching (as you've also observed), maybe we should
> > de-generalize it to do only that.  I think that allows us to make some
> > simplifying assumptions about the state of the world.
>
> Sounds good.
>
>
>         Stefan
>
>

[-- Attachment #1.2: Type: text/html, Size: 1717 bytes --]

[-- Attachment #2: 0001-elec-pair-Fix-bug-incorrectly-hiding-syntax-properti.patch --]
[-- Type: text/x-patch, Size: 8241 bytes --]

From fc3a85fc83fa3fd54a73002575d339e6bb7423b2 Mon Sep 17 00:00:00 2001
From: Allen Li <darkfeline@felesatra.moe>
Date: Sun, 26 Jun 2022 02:32:47 -0700
Subject: [PATCH] elec-pair: Fix bug incorrectly hiding
 syntax-propertize-function

The main bug that this is fixing is `syntax-propertize-function' being
hidden in `electric-pair--balance-info' when the original syntax table
is to be used, not `electric-pair-text-syntax-table'.

Notably, this causes `electric-pair-mode' to often misbehave in HTML
files when pairing angle brackets.

This commit also flushes the cache before installing
`electric-pair-text-syntax-table', to prevent cached syntax for the
original table from affecting things.
---
 lisp/elec-pair.el | 82 +++++++++++++++++++++++++----------------------
 1 file changed, 43 insertions(+), 39 deletions(-)

diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el
index bbed955a39..dab37c5110 100644
--- a/lisp/elec-pair.el
+++ b/lisp/elec-pair.el
@@ -188,6 +188,25 @@ electric-pair-conservative-inhibit
    ;; I also find it often preferable not to pair next to a word.
    (eq (char-syntax (following-char)) ?w)))
 
+(cl-defmacro electric-pair--with-text-syntax ((&optional start) &rest body)
+  "Run BODY with `electric-pair-text-syntax-table' active.
+This ensures that all syntax related values are set properly and the
+`syntax-ppss' cache is cleared before and after.
+In particular, this must be used 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 ((&optional form) body)) (indent 1))
+  (let ((start-var (make-symbol "start")))
+    `(let ((syntax-propertize-function nil)
+           (,start-var ,(or start '(point))))
+       (syntax-ppss-flush-cache ,start-var)
+       (unwind-protect
+           (with-syntax-table electric-pair-text-syntax-table
+             ,@body)
+         (syntax-ppss-flush-cache ,start-var)))))
+
 (defun electric-pair-syntax-info (command-event)
   "Calculate a list (SYNTAX PAIR UNCONDITIONAL STRING-OR-COMMENT-START).
 
@@ -202,13 +221,12 @@ electric-pair-syntax-info
          (post-string-or-comment (nth 8 (syntax-ppss (point))))
          (string-or-comment (and post-string-or-comment
                                  pre-string-or-comment))
-         (table (if string-or-comment
-                    electric-pair-text-syntax-table
-                  (syntax-table)))
-         (table-syntax-and-pair (with-syntax-table table
-                                  (list (char-syntax command-event)
-                                        (or (matching-paren command-event)
-                                            command-event))))
+         (table-syntax-and-pair (cl-flet ((f () (list (char-syntax command-event)
+                                                      (or (matching-paren command-event)
+                                                          command-event))))
+                                  (if string-or-comment
+                                      (electric-pair--with-text-syntax () (f))
+                                    (f))))
          (fallback (if string-or-comment
                        (append electric-pair-text-pairs
                                electric-pair-pairs)
@@ -237,22 +255,6 @@ electric-pair--insert
         (electric-layout-allow-duplicate-newlines t))
     (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 #'ignore)
-           (,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'.
 
@@ -271,8 +273,7 @@ electric-pair--syntax-ppss
                               (skip-syntax-forward " >!")
                               (point)))))
     (if s-or-c-start
-        (electric-pair--with-uncached-syntax (electric-pair-text-syntax-table
-                                              s-or-c-start)
+        (electric-pair--with-text-syntax (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))
@@ -301,9 +302,6 @@ electric-pair--balance-info
 If point is not enclosed by any lists, return ((t) . (t))."
   (let* (innermost
          outermost
-         (table (if string-or-comment
-                    electric-pair-text-syntax-table
-                  (syntax-table)))
          (at-top-level-or-equivalent-fn
           ;; called when `scan-sexps' ran perfectly, when it found
           ;; a parenthesis pointing in the direction of travel.
@@ -325,11 +323,12 @@ electric-pair--balance-info
                         (cond ((< direction 0)
                                (condition-case nil
                                    (eq (char-after pos)
-                                       (electric-pair--with-uncached-syntax
-                                           (table)
-                                         (matching-paren
-                                          (char-before
-                                           (scan-sexps (point) 1)))))
+                                       (cl-flet ((f () (matching-paren
+                                                        (char-before
+                                                         (scan-sexps (point) 1)))))
+                                         (if string-or-comment
+                                             (electric-pair--with-text-syntax () (f))
+                                           (f))))
                                  (scan-error nil)))
                               (t
                                ;; In this case, no need to use
@@ -343,7 +342,9 @@ electric-pair--balance-info
                                       (opener (char-after start)))
                                  (and start
                                       (eq (char-before pos)
-                                          (or (with-syntax-table table
+                                          (or (if string-or-comment
+                                                  (electric-pair--with-text-syntax ()
+                                                    (matching-paren opener))
                                                 (matching-paren opener))
                                               opener))))))))
                      (actual-pair (if (> direction 0)
@@ -356,11 +357,14 @@ electric-pair--balance-info
     (save-excursion
       (while (not outermost)
         (condition-case err
-            (electric-pair--with-uncached-syntax (table)
-              (scan-sexps (point) (if (> direction 0)
-                                      (point-max)
-                                    (- (point-max))))
-              (funcall at-top-level-or-equivalent-fn))
+            (cl-flet ((f ()
+                         (scan-sexps (point) (if (> direction 0)
+                                                 (point-max)
+                                               (- (point-max))))
+                         (funcall at-top-level-or-equivalent-fn)))
+              (if string-or-comment
+                  (electric-pair--with-text-syntax () (f))
+                (f)))
           (scan-error
            (cond ((or
                    ;; some error happened and it is not of the "ended
-- 
2.37.0


  reply	other threads:[~2022-07-02 10:48 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-18 23:52 bug#49629: 27.2; electric-pair-mode doesn't work for angle brackets in HTML file Allen Li
2021-07-22  7:03 ` bug#49629: Acknowledgement (27.2; electric-pair-mode doesn't work for angle brackets in HTML file) Allen Li
2021-07-22 23:34   ` bug#49629: 27.2; electric-pair-mode doesn't work for angle brackets in HTML file Lars Ingebrigtsen
2021-07-25 10:08     ` Allen Li
2021-07-28 15:42       ` Lars Ingebrigtsen
2021-08-01  5:06         ` Allen Li
2021-08-01 10:41           ` Lars Ingebrigtsen
2021-12-09 10:31             ` Allen Li
2021-12-09 13:30               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-12-24 10:07                 ` Allen Li
2021-12-24 14:23                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-26  8:41               ` Allen Li
2022-06-26  9:38                 ` Allen Li
2022-06-26 12:17                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-27  0:33                     ` Allen Li
2022-06-27 12:39                       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-02 10:48                         ` Allen Li [this message]
2022-07-03 10:32                           ` Lars Ingebrigtsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CADbSrJxwDGJAxbQreYVTrf3xdyH4TSEKKbiHKAu6c2KJC=EBMQ@mail.gmail.com' \
    --to=darkfeline@felesatra.moe \
    --cc=49629@debbugs.gnu.org \
    --cc=larsi@gnus.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=npostavs@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).