[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/rainbow-delimiters 2561e9853c 052/188: Attempt to fix issu
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/rainbow-delimiters 2561e9853c 052/188: Attempt to fix issue #25. |
Date: |
Sat, 1 Jan 2022 00:58:52 -0500 (EST) |
branch: elpa/rainbow-delimiters
commit 2561e9853c0ae707be335dde9ea84adca914b6fb
Author: Fanael Linithien <fanael4@gmail.com>
Commit: Fanael Linithien <fanael4@gmail.com>
Attempt to fix issue #25.
---
rainbow-delimiters.el | 53 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 51 insertions(+), 2 deletions(-)
diff --git a/rainbow-delimiters.el b/rainbow-delimiters.el
index 13cbad3031..6c4f47036b 100644
--- a/rainbow-delimiters.el
+++ b/rainbow-delimiters.el
@@ -310,6 +310,53 @@ For example: 'rainbow-delimiters-depth-1-face'."
rainbow-delimiters-outermost-only-face-count)))))
"-face")))
+;;; Parse partial sexp cache
+
+;; If the block inside the delimiters is too big (where "too big" is
+;; in some way related to `jit-lock-chunk-size'), `syntax-ppss' will
+;; for some reason return wrong depth. Is it because we're misusing
+;; it? Is it because it's buggy? Nobody knows. But users do notice it,
+;; and have reported it as a bug. Hence this workaround: don't use
+;; `syntax-ppss' at all, use the low-level primitive instead. However,
+;; naively replacing `syntax-ppss' with `parse-partial-sexp' slows
+;; down the delimiter highlighting noticeably in big files. Therefore,
+;; we build a simple cache around it. This brings the speed to around
+;; what it used to be, while fixing the bug. See issue #25.
+
+;; TODO: maybe make the cache a little smarter than just caching the
+;; last call?
+
+(defvar rainbow-delimiters-parse-partial-sexp-cache nil
+ "Cache of the last `parse-partial-sexp' call.
+
+If it's nil, there's nothing in the cache. Otherwise, it's a cons
+cell, where car is the position for which `parse-partial-sexp' was
+called and cdr is the result of the call.")
+(make-variable-buffer-local 'rainbow-delimiters-parse-partial-sexp-cache)
+
+(defun rainbow-delimiters-syntax-ppss-flush-cache (beg _end)
+ "Flush the `parse-partial-sexp' cache starting at position BEG."
+ (when (and rainbow-delimiters-parse-partial-sexp-cache
+ (<= beg (car rainbow-delimiters-parse-partial-sexp-cache)))
+ (setq rainbow-delimiters-parse-partial-sexp-cache nil)))
+
+(defsubst rainbow-delimiters-syntax-ppss (pos)
+ "Parse-Partial-Sexp State at POS, defaulting to point.
+
+The returned value is the same as that of `parse-partial-sexp' from
+`point-min' to POS, except that positions 2 and 6 cannot be relied
+upon.
+
+This is essentialy `syntax-ppss', only specific to rainbow-delimiters
+to work around a bug."
+ (save-excursion
+ (let* ((cache rainbow-delimiters-parse-partial-sexp-cache)
+ (ppss (if (and cache (>= pos (car cache)))
+ (parse-partial-sexp (car cache) pos nil nil (cdr cache))
+ (parse-partial-sexp (point-min) pos))))
+ (setq rainbow-delimiters-parse-partial-sexp-cache (cons pos ppss))
+ ppss)))
+
;;; Nesting level
(defvar rainbow-delimiters-syntax-table nil
@@ -336,7 +383,7 @@ major-mode. The syntax table is constructed by the function
"Return # of nested levels of parens, brackets, braces LOC is inside of."
(let ((depth
(with-syntax-table rainbow-delimiters-syntax-table
- (car (syntax-ppss loc)))))
+ (car (rainbow-delimiters-syntax-ppss loc)))))
(if (>= depth 0)
depth
0))) ; ignore negative depths created by unmatched closing parens.
@@ -433,7 +480,7 @@ Returns t if char at loc meets one of the following
conditions:
- Inside a string.
- Inside a comment.
- Is an escaped char, e.g. ?\)"
- (let ((parse-state (syntax-ppss loc)))
+ (let ((parse-state (rainbow-delimiters-syntax-ppss loc)))
(or
(nth 3 parse-state) ; inside string?
(nth 4 parse-state) ; inside comment?
@@ -519,8 +566,10 @@ Used by jit-lock for dynamic highlighting."
nil "" nil ; No modeline lighter - it's already obvious when the mode is on.
(if (not rainbow-delimiters-mode)
(progn
+ (remove-hook 'before-change-functions
'rainbow-delimiters-syntax-ppss-flush-cache t)
(jit-lock-unregister 'rainbow-delimiters-propertize-region)
(rainbow-delimiters-unpropertize-region (point-min) (point-max)))
+ (add-hook 'before-change-functions
'rainbow-delimiters-syntax-ppss-flush-cache t t)
(jit-lock-register 'rainbow-delimiters-propertize-region t)
;; Create necessary syntax tables inheriting from current major-mode.
(set (make-local-variable 'rainbow-delimiters-syntax-table)
- [nongnu] elpa/rainbow-delimiters 0a4e4958ed 113/188: Add a missing or in rainbow-delimiters--char-ineligible-p., (continued)
- [nongnu] elpa/rainbow-delimiters 0a4e4958ed 113/188: Add a missing or in rainbow-delimiters--char-ineligible-p., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters 1473fbddce 116/188: Add a test suite., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters 89574443f0 117/188: Fix the Emacs 24.3-specific test failure., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters 30c6a4c1bc 118/188: Use the major mode's syntax table directly., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters 406ee45e7c 126/188: Rewrite the installation and usage instructions., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters 7b882c9489 138/188: Merge (let … (let* …)) => (let* …)., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters f57067cda5 140/188: Make Emacs 23 tests less verbose., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters 6e9e17e739 008/188: Add a 'global-rainbow-delimiters-mode' for enabling rainbow-delimiters in all buffers., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters daa1737a8f 011/188: Whitespace changes., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters f1ff54da71 051/188: Release version 1.3.5., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters 2561e9853c 052/188: Attempt to fix issue #25.,
ELPA Syncer <=
- [nongnu] elpa/rainbow-delimiters 4c94853583 007/188: Add an item to the TODO list., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters b9252e33d2 057/188: Remove unneeded require., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters b656f8c9cd 064/188: Wrap rainbow-delimiters-{un, }propertize-region with with-silent-modifications and with-syntax-table., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters a1dd352c1a 059/188: Fix docstring style errors reported by checkdoc., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters 3dfd3fa9b1 054/188: Use sorted-list caching to improve large-file performance, ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters fc70c7ec67 058/188: Use standard form of the footer comment., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters 949078cfd7 042/188: Ignoring compiled files, ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters ee4519d20a 046/188: Use face symbols instead of face strings to better cooperate with htmlize., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters 36df2e014c 067/188: Add code to highlight mismatched closing delimiters., ELPA Syncer, 2022/01/01
- [nongnu] elpa/rainbow-delimiters c4c127992a 071/188: Use font-lock instead of jit-lock., ELPA Syncer, 2022/01/01