unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Stefan Monnier via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Eli Zaretskii <eliz@gnu.org>
Cc: gerd.moellmann@gmail.com, psainty@orcon.net.nz, larsi@gnus.org,
	Emacs-hacker2018@jovi.net, 45898@debbugs.gnu.org
Subject: bug#45898: 27.1; wedged in redisplay again
Date: Wed, 29 Jun 2022 17:07:45 -0400	[thread overview]
Message-ID: <jwvilojnqfb.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <83pmir5lwc.fsf@gnu.org> (Eli Zaretskii's message of "Wed, 29 Jun 2022 22:07:15 +0300")

>> How 'bout the patch below?
> Thanks.

Doesn't work: the looping around font-lock-extend-region-functions ends
up calling `font-lock-extend-region-wholelines` repeatedly as long as
the bounds a grown and so the bounds keep growing until we're back at
square one.

The patch below addresses this problem by truncating in a more careful
way, so `font-lock-extend-region-wholelines` is idempotent
(i.e. repeated calls don't keep growing the bounds).  It's also careful
to use that same "chunking" in syntax.el and in the antiblink code of
jit-lock.  Tracing `syntax-ppss` and `syntax-propertize-wholelines`
suggests that this patch is sufficient to keep most of the work "local"
rather than applying to the whole line/file all the time.

>> It doesn't seem to make much difference on the `medium_line.json`
>> example from Phil, tho :-(
> In what case does it make much difference?

None that I can see :-(

> And how did you test whether it makes a difference?

I just did

    src/emacs -Q ~/tmp/medium_line.json

and then tried to move around in the buffer, search with Isearch, and
insert a few chars.
I don't notice any difference with or without the patch :-(



        Stefan


diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el
index 36b0c56e953..e1be3015838 100644
--- a/lisp/emacs-lisp/syntax.el
+++ b/lisp/emacs-lisp/syntax.el
@@ -124,15 +124,49 @@ syntax-propertize-extend-region-functions
 otherwise nil.  That construct can be a two character comment
 delimiter or an Escaped or Char-quoted character."))
 
-(defun syntax-propertize-wholelines (start end)
-  "Extend the region delimited by START and END to whole lines.
+(defvar syntax-wholeline-max 10000
+  "Maximum line length for syntax operations.
+If lines are longer than that, syntax operations will treat them as chunks
+of this size.  Misfontification may then occur.
+This is a tradeoff between correctly applying the syntax rules,
+and avoiding major slowdown on pathologically long lines.")
+
+(defun syntax--lbp (&optional arg)
+  "Like `line-beginning-position' but obeying `syntax-wholeline-max'."
+  (let ((pos (point))
+        (res (line-beginning-position arg)))
+    (cond
+     ((< (abs (- pos res)) syntax-wholeline-max) res)
+     ;; For lines that are too long, round to the nearest multiple of
+     ;; `syntax-wholeline-max'.  We use rounding rather than just
+     ;; (min res (+ pos syntax-wholeline-max)) so that repeated calls
+     ;; to `syntax-propertize-wholelines' don't keep growing the bounds,
+     ;; i.e. it really behaves like additional line-breaks.
+     ((< res pos)
+      (let ((max syntax-wholeline-max))
+        (max (point-min) (* max (truncate pos max)))))
+     (t
+      (let ((max syntax-wholeline-max))
+        (min (point-max) (* max (ceiling pos max))))))))
+
+(defun syntax-propertize-wholelines (beg end)
+  "Extend the region delimited by BEG and END to whole lines.
 This function is useful for
 `syntax-propertize-extend-region-functions';
 see Info node `(elisp) Syntax Properties'."
-  (goto-char start)
-  (cons (line-beginning-position)
-        (progn (goto-char end)
-               (if (bolp) (point) (line-beginning-position 2)))))
+  ;; This let-binding was taken from
+  ;; `font-lock-extend-region-wholelines' where it was used to avoid
+  ;; inf-looping (Bug#21615) but for some reason it was not applied
+  ;; here in syntax.el and was used only for the "beg" side.
+  (let ((inhibit-field-text-motion t))
+    (let ((new-beg (progn (goto-char beg)
+                          (if (bolp) beg
+                            (syntax--lbp))))
+          (new-end (progn (goto-char end)
+                          (if (bolp) end
+                            (syntax--lbp 2)))))
+      (unless (and (eql beg new-beg) (eql end new-end))
+        (cons new-beg new-end)))))
 
 (defun syntax-propertize-multiline (beg end)
   "Let `syntax-propertize' pay attention to the syntax-multiline property."
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index df0a26f4d0f..7eeaf2f547f 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -1260,18 +1260,11 @@ font-lock-extend-region-multiline
 
 (defun font-lock-extend-region-wholelines ()
   "Move fontification boundaries to beginning of lines."
-  (let ((changed nil))
-    (goto-char font-lock-beg)
-    (unless (bolp)
-      (setq changed t font-lock-beg
-            (let ((inhibit-field-text-motion t))
-              (line-beginning-position))))
-    (goto-char font-lock-end)
-    (unless (bolp)
-      (unless (eq font-lock-end
-                  (setq font-lock-end (line-beginning-position 2)))
-        (setq changed t)))
-    changed))
+  (let ((new (syntax-propertize-wholelines font-lock-beg font-lock-end)))
+    (when new
+      (setq font-lock-beg (car new))
+      (setq font-lock-end (cdr new))
+      t)))
 
 (defun font-lock-default-fontify-region (beg end loudly)
   "Fontify the text between BEG and END.
@@ -1565,7 +1558,7 @@ font-lock-apply-syntactic-highlight
 	(or (nth 3 highlight)
 	    (error "No match %d in highlight %S" match highlight))
       (when (and (consp value) (not (numberp (car value))))
-	(setq value (eval value)))
+	(setq value (eval value t)))
       (when (stringp value) (setq value (string-to-syntax value)))
       ;; Flush the syntax-cache.  I believe this is not necessary for
       ;; font-lock's use of syntax-ppss, but I'm not 100% sure and it can
@@ -1589,7 +1582,7 @@ font-lock-fontify-syntactic-anchored-keywords
 LIMIT can be modified by the value of its PRE-MATCH-FORM."
   (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights
 	;; Evaluate PRE-MATCH-FORM.
-	(pre-match-value (eval (nth 1 keywords))))
+	(pre-match-value (eval (nth 1 keywords) t)))
     ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line.
     (if (and (numberp pre-match-value) (> pre-match-value (point)))
 	(setq limit pre-match-value)
@@ -1605,7 +1598,7 @@ font-lock-fontify-syntactic-anchored-keywords
 	  (font-lock-apply-syntactic-highlight (car highlights))
 	  (setq highlights (cdr highlights)))))
     ;; Evaluate POST-MATCH-FORM.
-    (eval (nth 2 keywords))))
+    (eval (nth 2 keywords) t)))
 
 (defun font-lock-fontify-syntactic-keywords-region (start end)
   "Fontify according to `font-lock-syntactic-keywords' between START and END.
@@ -1718,7 +1711,7 @@ font-lock-apply-highlight
 	;; No match but we might not signal an error.
 	(or (nth 3 highlight)
 	    (error "No match %d in highlight %S" match highlight))
-      (let ((val (eval (nth 1 highlight))))
+      (let ((val (eval (nth 1 highlight) t)))
 	(when (eq (car-safe val) 'face)
 	  (add-text-properties start end (cddr val))
 	  (setq val (cadr val)))
@@ -1753,7 +1746,7 @@ font-lock-fontify-anchored-keywords
   (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights
 	(lead-start (match-beginning 0))
 	;; Evaluate PRE-MATCH-FORM.
-	(pre-match-value (eval (nth 1 keywords))))
+	(pre-match-value (eval (nth 1 keywords) t)))
     ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line.
     (if (not (and (numberp pre-match-value) (> pre-match-value (point))))
 	(setq limit (line-end-position))
@@ -1778,7 +1771,7 @@ font-lock-fontify-anchored-keywords
 	  (font-lock-apply-highlight (car highlights))
 	  (setq highlights (cdr highlights)))))
     ;; Evaluate POST-MATCH-FORM.
-    (eval (nth 2 keywords))))
+    (eval (nth 2 keywords) t)))
 
 (defun font-lock-fontify-keywords-region (start end &optional loudly)
   "Fontify according to `font-lock-keywords' between START and END.
@@ -1884,7 +1877,7 @@ font-lock-compile-keyword
   (cond ((or (functionp keyword) (nlistp keyword)) ; MATCHER
 	 (list keyword '(0 font-lock-keyword-face)))
 	((eq (car keyword) 'eval)		; (eval . FORM)
-	 (font-lock-compile-keyword (eval (cdr keyword))))
+	 (font-lock-compile-keyword (eval (cdr keyword) t)))
 	((eq (car-safe (cdr keyword)) 'quote)	; (MATCHER . 'FORM)
 	 ;; If FORM is a FACENAME then quote it.  Otherwise ignore the quote.
 	 (if (symbolp (nth 2 keyword))
@@ -1905,7 +1898,7 @@ font-lock-eval-keywords
       keywords
     (font-lock-eval-keywords (if (fboundp keywords)
 				 (funcall keywords)
-			       (eval keywords)))))
+			       (eval keywords t)))))
 
 (defun font-lock-value-in-major-mode (values)
   "If VALUES is a list, use `major-mode' as a key and return the `assq' value.
diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el
index 17969d57620..a3ada443702 100644
--- a/lisp/jit-lock.el
+++ b/lisp/jit-lock.el
@@ -242,20 +242,20 @@ jit-lock-mode
     (when (and jit-lock-stealth-time (null jit-lock-stealth-timer))
       (setq jit-lock-stealth-timer
             (run-with-idle-timer jit-lock-stealth-time t
-                                 'jit-lock-stealth-fontify)))
+                                 #'jit-lock-stealth-fontify)))
 
     ;; Create, but do not activate, the idle timer for repeated
     ;; stealth fontification.
     (when (and jit-lock-stealth-time (null jit-lock-stealth-repeat-timer))
       (setq jit-lock-stealth-repeat-timer (timer-create))
       (timer-set-function jit-lock-stealth-repeat-timer
-                          'jit-lock-stealth-fontify '(t)))
+                          #'jit-lock-stealth-fontify '(t)))
 
     ;; Init deferred fontification timer.
     (when (and jit-lock-defer-time (null jit-lock-defer-timer))
       (setq jit-lock-defer-timer
             (run-with-idle-timer jit-lock-defer-time t
-                                 'jit-lock-deferred-fontify)))
+                                 #'jit-lock-deferred-fontify)))
 
     ;; Initialize contextual fontification if requested.
     (when (eq jit-lock-contextually t)
@@ -265,13 +265,13 @@ jit-lock-mode
                                    (lambda ()
                                      (unless jit-lock--antiblink-grace-timer
                                        (jit-lock-context-fontify))))))
-      (add-hook 'post-command-hook 'jit-lock--antiblink-post-command nil t)
+      (add-hook 'post-command-hook #'jit-lock--antiblink-post-command nil t)
       (setq jit-lock-context-unfontify-pos
             (or jit-lock-context-unfontify-pos (point-max))))
 
     ;; Setup our hooks.
-    (add-hook 'after-change-functions 'jit-lock-after-change nil t)
-    (add-hook 'fontification-functions 'jit-lock-function nil t))
+    (add-hook 'after-change-functions #'jit-lock-after-change nil t)
+    (add-hook 'fontification-functions #'jit-lock-function nil t))
 
    ;; Turn Just-in-time Lock mode off.
    (t
@@ -294,8 +294,9 @@ jit-lock-mode
         (setq jit-lock-defer-timer nil)))
 
     ;; Remove hooks.
-    (remove-hook 'after-change-functions 'jit-lock-after-change t)
-    (remove-hook 'fontification-functions 'jit-lock-function))))
+    (remove-hook 'post-command-hook #'jit-lock--antiblink-post-command t)
+    (remove-hook 'after-change-functions #'jit-lock-after-change t)
+    (remove-hook 'fontification-functions #'jit-lock-function))))
 
 (define-minor-mode jit-lock-debug-mode
   "Minor mode to help debug code run from jit-lock.
@@ -707,8 +708,8 @@ jit-lock-after-change
               (min jit-lock-context-unfontify-pos jit-lock-start))))))
 
 (defun jit-lock--antiblink-post-command ()
-  (let* ((new-l-b-p (copy-marker (line-beginning-position)))
-         (l-b-p-2 (line-beginning-position 2))
+  (let* ((new-l-b-p (copy-marker (syntax--lbp)))
+         (l-b-p-2 (syntax--lbp 2))
          (same-line
           (and jit-lock-antiblink-grace
                (not (= new-l-b-p l-b-p-2))






  reply	other threads:[~2022-06-29 21:07 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-15 18:13 bug#45898: 27.1; wedged in redisplay again Devon Sean McCullough
2022-06-07 13:37 ` Lars Ingebrigtsen
2022-06-07 14:00   ` Eli Zaretskii
     [not found]     ` <b7f81bfc-bbfb-83bc-3660-d0b1474498f7@jovi.net>
2022-06-07 15:53       ` Eli Zaretskii
2022-06-08 11:47     ` Lars Ingebrigtsen
2022-06-08 14:08       ` Eli Zaretskii
2022-06-08 15:58         ` Eli Zaretskii
2022-06-09 10:30           ` Lars Ingebrigtsen
2022-06-09 10:45             ` Eli Zaretskii
2022-06-09 11:04               ` Lars Ingebrigtsen
2022-06-09 13:09                 ` Eli Zaretskii
2022-06-09 13:36                   ` Lars Ingebrigtsen
2022-06-09 15:56                     ` Eli Zaretskii
2022-06-10  9:02                       ` Lars Ingebrigtsen
2022-06-12  9:48                         ` Eli Zaretskii
2022-06-12 10:23                           ` Lars Ingebrigtsen
2022-06-12 14:23                             ` Eli Zaretskii
2022-06-12 18:02                               ` Eli Zaretskii
2022-06-13 12:10                               ` Lars Ingebrigtsen
2022-06-13 12:57                                 ` Eli Zaretskii
2022-06-13 22:40                                   ` Phil Sainty
2022-06-14 12:45                                     ` Eli Zaretskii
2022-06-18  8:01                                       ` Eli Zaretskii
2022-06-20 11:58                                         ` Eli Zaretskii
2022-06-20 19:11                                           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-21 10:14                                             ` Eli Zaretskii
2022-06-21 20:38                                         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-22  2:33                                           ` Eli Zaretskii
2022-06-22 23:39                                             ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-23  6:08                                               ` Eli Zaretskii
2022-06-23 21:14                                                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-24  7:57                                                   ` Eli Zaretskii
2022-06-25  4:54                                                     ` Gerd Möllmann
2022-06-25  6:29                                                       ` Eli Zaretskii
2022-06-25  7:47                                                         ` Eli Zaretskii
2022-06-25  8:18                                                           ` Gerd Möllmann
2022-06-25  9:49                                                         ` Gerd Möllmann
2022-06-25  9:57                                                           ` Eli Zaretskii
2022-06-25 11:10                                                             ` Gerd Möllmann
2022-06-25 11:29                                                               ` Eli Zaretskii
2022-06-25 12:20                                                                 ` Gerd Möllmann
2022-06-25 12:54                                                                   ` Eli Zaretskii
2022-06-25 12:57                                                                     ` Gerd Möllmann
2022-06-29 16:18                                                     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-29 19:07                                                       ` Eli Zaretskii
2022-06-29 21:07                                                         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2022-06-30  5:14                                                           ` Eli Zaretskii
2022-06-30 17:22                                                             ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-30 18:35                                                               ` Eli Zaretskii
2022-06-30 19:56                                                                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-01  4:42                                                                   ` Gerd Möllmann
2022-07-01  6:04                                                                     ` Eli Zaretskii
2022-07-01  8:49                                                                       ` Gerd Möllmann
2022-07-01 10:31                                                                         ` Eli Zaretskii
2022-07-01 11:04                                                                           ` Gerd Möllmann
2022-07-01 11:12                                                                             ` Eli Zaretskii
2022-07-01 11:33                                                                               ` Gerd Möllmann
2022-07-01 11:44                                                                       ` Gerd Möllmann
2022-07-01 12:35                                                                         ` Gerd Möllmann
2022-07-01 12:56                                                                           ` Eli Zaretskii
2022-07-01 12:39                                                                         ` Eli Zaretskii
2022-07-01  5:27                                                                   ` Eli Zaretskii
2022-07-01 12:14                                                                     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-01 12:51                                                                       ` Eli Zaretskii
2022-07-01 14:38                                                                         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-01 15:43                                                                           ` Eli Zaretskii
2022-06-14 12:00                                   ` Lars Ingebrigtsen
2022-06-14 13:00                                     ` Eli Zaretskii
2022-06-09 10:25         ` Lars Ingebrigtsen
2022-06-09 10:40           ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-09 10:41           ` Eli Zaretskii
2022-06-09 10:48             ` Lars Ingebrigtsen
2022-06-09 13:06               ` Eli Zaretskii
     [not found] <165605725704.24125.17210424600068379407@vcs2.savannah.gnu.org>
     [not found] ` <20220624075417.BFA82C0169C@vcs2.savannah.gnu.org>
     [not found]   ` <87wnd6v34k.fsf@gnus.org>
     [not found]     ` <83mte2coqg.fsf@gnu.org>
     [not found]       ` <87fsjuqpzi.fsf@gnus.org>
     [not found]         ` <83k096clsx.fsf@gnu.org>
     [not found]           ` <8735fup5oh.fsf@gnus.org>
     [not found]             ` <83a6a2cher.fsf@gnu.org>
     [not found]               ` <874k09nau4.fsf@gnus.org>
2022-06-25  7:17                 ` Eli Zaretskii
2022-06-25 10:10                   ` Lars Ingebrigtsen
2022-06-25 11:21                     ` Eli Zaretskii

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=jwvilojnqfb.fsf-monnier+emacs@gnu.org \
    --to=bug-gnu-emacs@gnu.org \
    --cc=45898@debbugs.gnu.org \
    --cc=Emacs-hacker2018@jovi.net \
    --cc=eliz@gnu.org \
    --cc=gerd.moellmann@gmail.com \
    --cc=larsi@gnus.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=psainty@orcon.net.nz \
    /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).