diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2022-06-30 13:20:33 -0400 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2022-06-30 13:20:33 -0400 |
commit | 15b2138719b34083967001c3903e7560d5e0947c (patch) | |
tree | b37d992e6f31140c051fc2b6bae6fb84f92addb6 /lisp/emacs-lisp | |
parent | 77e99dcacb57cae558f833334a8367fbc9b4fd8a (diff) | |
download | emacs-15b2138719b34083967001c3903e7560d5e0947c.tar.gz emacs-15b2138719b34083967001c3903e7560d5e0947c.tar.bz2 emacs-15b2138719b34083967001c3903e7560d5e0947c.zip |
(syntax-wholeline-max): New var
Try and reduce the pain caused by font-lock and syntax-propertize's
wholeline-based operation in buffers made up of a few very long lines
(bug#45898).
* lisp/emacs-lisp/syntax.el (syntax-wholeline-max): New var.
(syntax--lbp): New function.
(syntax-propertize-wholelines): Use it.
* lisp/jit-lock.el (jit-lock--antiblink-post-command): Use `syntax--lbp`.
* lisp/font-lock.el (font-lock-extend-region-wholelines): Rewrite,
using `syntax-propertize-wholelines`.
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r-- | lisp/emacs-lisp/syntax.el | 46 |
1 files changed, 40 insertions, 6 deletions
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 @@ When the last position scanned holds the first character of a 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." |