branch: elpa/logview
commit 0a1b3a8268a45a0c5a682bc04546dec056fb1950
Author: Paul Pogonyshev <pogonys...@gmail.com>
Commit: Paul Pogonyshev <pogonys...@gmail.com>

    Prevent certain errors on Emacs 29 (up to a full freeze) by preventively 
disabling its long-line optimization; fail fast if that doesn't help.
---
 logview.el | 62 ++++++++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 46 insertions(+), 16 deletions(-)

diff --git a/logview.el b/logview.el
index a38feab48a..a0819423cb 100644
--- a/logview.el
+++ b/logview.el
@@ -644,6 +644,7 @@ this face is used."
 (defvar-local logview--custom-submode-guessed-with 0)
 
 
+;; Don't access these as variables directly, use functions with the same name 
instead.
 (defvar-local logview--point-min nil)
 (defvar-local logview--point-max nil)
 
@@ -859,13 +860,33 @@ works for \\[logview-set-navigation-view] and 
\\[logview-highlight-view-entries]
        (with-silent-modifications
          ,@body))))
 
-(defmacro logview--std-temporarily-widening (&rest body)
+(defmacro logview--temporarily-widening (&rest body)
+  "Execute BODY with the current buffer fully widened.
+Original point restrictions, if any, will not be possible to find
+inside BODY.  In most cases (also if not sure) you should use
+macro `logview--std-temporarily-widening' instead."
   (declare (indent 0) (debug t))
   `(save-restriction
-     (let ((logview--point-min (logview--point-min))
-           (logview--point-max (logview--point-max)))
-       (widen)
-       ,@body)))
+     (widen)
+     ,@(when (>= emacs-major-version 29)
+         ;; It is better to fail hard now than to face an arbitrary failure 
later.  In
+         ;; particular, an infinite loop in fontification code can 
irreversibly freeze
+         ;; Emacs, but this is of course "not a bug":
+         ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57804
+         `((unless (and (= (point-min) 1) (= (point-max) (1+ (buffer-size))))
+             (error "Logview is incompatible with locked narrowing; see 
https://github.com/doublep/logview#locked-narrowing";))))
+     ,@body))
+
+(defmacro logview--std-temporarily-widening (&rest body)
+  "Execute BODY with the current buffer fully widened.
+Original point restrictions are available as return values of
+functions `logview--point-min' and `logview--point-max'.  This
+macro can be nested, with inner calls not changing results of the
+two functions (available since the first call) further."
+  (declare (indent 0) (debug t))
+  `(let ((logview--point-min (logview--point-min))
+         (logview--point-max (logview--point-max)))
+     (logview--temporarily-widening ,@body)))
 
 (defmacro logview--locate-current-entry (entry start &rest body)
   (declare (indent 2) (debug (symbolp symbolp body)))
@@ -1114,9 +1135,16 @@ interfere with editing) or if submode wasn't guessed
 successfully.")
 
 
+;; Emacs 29 (snapshots); need to set it to nil.
+(defvar long-line-threshold)
+
 ;;;###autoload
 (define-derived-mode logview-mode nil "Logview"
   "Major mode for viewing and filtering various log files."
+  ;; Logview is incompatible with locked narrowing of Emacs 29.  Set this 
variable in hope
+  ;; this prevents it from ever happening.  See 
`logview--temporarily-widening'.
+  (when (boundp 'long-line-threshold)
+    (setq-local long-line-threshold nil))
   (logview--update-keymap)
   (add-hook 'read-only-mode-hook #'logview--update-keymap nil t)
   (setq font-lock-defaults (copy-sequence logview-font-lock-defaults))
@@ -2707,8 +2735,7 @@ returns non-nil."
         (if (and (>= temporary-size reassurance-chars)
                      (string= (buffer-substring-no-properties 1 (1+ 
reassurance-chars))
                               (with-current-buffer buffer
-                                (save-restriction
-                                  (widen)
+                                (logview--std-temporarily-widening
                                   (buffer-substring-no-properties compare-from 
size)))))
             (if (= temporary-size reassurance-chars)
                 (message "Backing file %s hasn't grown" file)
@@ -2718,8 +2745,7 @@ returns non-nil."
                       ;; This is to avoid unnecessary confirmation about
                       ;; modifying a buffer with externally changed file.
                       (buffer-file-name  nil))
-                  (save-restriction
-                    (widen)
+                  (logview--std-temporarily-widening
                     (save-excursion
                       (goto-char (point-max))
                       (insert-buffer-substring-no-properties temporary (1+ 
reassurance-chars) (1+ temporary-size))))
@@ -2732,16 +2758,17 @@ returns non-nil."
 
 ;;; Internal functions (except helpers for specific command groups).
 
-(defvar inhibit-message)
-
 (defmacro logview--internal-log (format-string &rest arguments)
   `(let ((inhibit-message t))
      (message ,format-string ,@arguments)))
 
 (defun logview--guess-submode ()
   (save-excursion
-    (save-restriction
-      (widen)
+    ;; Need access to the buffer start, regardless of any narrowing.  Also, 
don't want
+    ;; original narrowing to have any effect on anything (see uses of 
corresponding
+    ;; functions that access it; not even sure they are even called from here, 
but that
+    ;; doesn't matter), that's why not `std'.
+    (logview--temporarily-widening
       (let ((line-number       0)
             (remaining-attemps (if (and (integerp logview-max-promising-lines) 
(> logview-max-promising-lines 0))
                                    logview-max-promising-lines
@@ -3672,7 +3699,10 @@ This list is preserved across Emacs session in
 
 (defun logview--fontify-region (region-start region-end loudly)
   (when (logview-initialized-p)
-    (logview--std-temporarily-widening
+    ;; We are basically managing narrowing indirectly, by not fontifying 
further than
+    ;; `region-end' (possibly expanded).  Not using `std' here to prevent
+    ;; `logview--iterate-entries-forward' from stopping early because of outer 
narrowing.
+    (logview--temporarily-widening
       ;; We are very fast.  Don't fontify too little to avoid overhead.
       ;; FIXME: See `font-lock-extend-region-functions'.  Might want to reuse 
that instead.
       (when (and (< region-end (point-max)) (not (get-text-property (1+ 
region-end) 'fontified)))
@@ -3916,9 +3946,9 @@ This list is preserved across Emacs session in
 (defun logview-filter-edit--font-lock-region (region-begin region-end 
&optional _old-length)
   (save-excursion
     (save-match-data
-      (save-restriction
+      ;; Not even in a Logview mode buffer, not using `std'.
+      (logview--temporarily-widening
         (with-silent-modifications
-          (widen)
           (goto-char region-begin)
           (forward-line 0)
           ;; Never try to parse from the middle of a multiline filter.

Reply via email to