-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Invalid highlighting when a delimiter is the second char of a comment opening #15
Comments
WIP patch, needs testcases and comments: rainbow-delimiters.el | 55 +++++++++++++++++++++++++++------------------------
1 file changed, 29 insertions(+), 26 deletions(-)
diff --git a/rainbow-delimiters.el b/rainbow-delimiters.el
index 8457bc6..7208335 100644
--- a/rainbow-delimiters.el
+++ b/rainbow-delimiters.el
@@ -205,15 +205,12 @@ Returns t if char at loc meets one of the following conditions:
(nth 5 ppss) ; escaped according to the syntax table?
;; Note: no need to consider single-char openers, they're already handled
;; by looking at ppss.
- (cond
- ;; Two character opener, LOC at the first character?
- ((/= 0 (logand #x10000 delim-syntax-code))
+ ;; Two character opener, LOC at the first character?
+ (when (/= 0 (logand #x10000 delim-syntax-code))
(/= 0 (logand #x20000 (or (car (syntax-after (1+ loc))) 0))))
- ;; Two character opener, LOC at the second character?
- ((/= 0 (logand #x20000 delim-syntax-code))
- (/= 0 (logand #x10000 (or (car (syntax-after (1- loc))) 0))))
- (t
- nil))))
+ ;; Two character opener, LOC at the second character?
+ (when (/= 0 (logand #x20000 delim-syntax-code))
+ (/= 0 (logand #x10000 (or (car (syntax-after (1- loc))) 0))))))
;; Main function called by font-lock.
(defun rainbow-delimiters--propertize (end)
@@ -222,28 +219,34 @@ Returns t if char at loc meets one of the following conditions:
Used by font-lock for dynamic highlighting."
(let* ((inhibit-point-motion-hooks t)
(last-ppss-pos (point))
- (ppss (syntax-ppss)))
+ (last-ppss (syntax-ppss last-ppss-pos))
+ (last-delim-pos 0))
(while (> end (progn (skip-syntax-forward "^()" end)
(point)))
(let* ((delim-pos (point))
(delim-syntax (syntax-after delim-pos)))
- (setq ppss (parse-partial-sexp last-ppss-pos delim-pos nil nil ppss))
- (setq last-ppss-pos delim-pos)
- ;; `skip-syntax-forward' leaves the point at the delimiter, move past
- ;; it.
- (forward-char)
- (let ((delim-syntax-code (car delim-syntax)))
- (cond
- ((rainbow-delimiters--char-ineligible-p delim-pos ppss delim-syntax-code)
- nil)
- ((= 4 (logand #xFFFF delim-syntax-code))
- ;; The (1+ ...) is needed because `parse-partial-sexp' returns the
- ;; depth at the opening delimiter, not in the block being started.
- (rainbow-delimiters--apply-color delim-pos (1+ (nth 0 ppss)) t))
- (t
- ;; Not an opening delimiter, so it's a closing delimiter.
- (let ((matches-p (eq (cdr delim-syntax) (char-after (nth 1 ppss)))))
- (rainbow-delimiters--apply-color delim-pos (nth 0 ppss) matches-p))))))))
+ (let ((pos-before-delim (1- delim-pos)))
+ (when (and (> (- pos-before-delim last-delim-pos) 1)
+ (> pos-before-delim last-ppss-pos))
+ (setq last-ppss (parse-partial-sexp last-ppss-pos pos-before-delim nil nil last-ppss))
+ (setq last-ppss-pos pos-before-delim)))
+ (setq last-delim-pos delim-pos)
+ (let ((ppss (parse-partial-sexp last-ppss-pos delim-pos nil nil last-ppss)))
+ ;; `skip-syntax-forward' leaves the point at the delimiter, move past
+ ;; it.
+ (forward-char)
+ (let ((delim-syntax-code (car delim-syntax)))
+ (cond
+ ((rainbow-delimiters--char-ineligible-p delim-pos ppss delim-syntax-code)
+ nil)
+ ((= 4 (logand #xFFFF delim-syntax-code))
+ ;; The (1+ ...) is needed because `parse-partial-sexp' returns the
+ ;; depth at the opening delimiter, not in the block being started.
+ (rainbow-delimiters--apply-color delim-pos (1+ (nth 0 ppss)) t))
+ (t
+ ;; Not an opening delimiter, so it's a closing delimiter.
+ (let ((matches-p (eq (cdr delim-syntax) (char-after (nth 1 ppss)))))
+ (rainbow-delimiters--apply-color delim-pos (nth 0 ppss) matches-p)))))))))
;; We already fontified the delimiters, tell font-lock there's nothing more
;; to do.
nil) |
A better "testcase", which has the nice property of breaking when e.g. the 1 in
|
The problem is that, for some reason, |
A patch that tries to avoid quadratic behavior: diff --git a/rainbow-delimiters.el b/rainbow-delimiters.el
index 8457bc6..15e3ed8 100644
--- a/rainbow-delimiters.el
+++ b/rainbow-delimiters.el
@@ -205,15 +205,12 @@ Returns t if char at loc meets one of the following conditions:
(nth 5 ppss) ; escaped according to the syntax table?
;; Note: no need to consider single-char openers, they're already handled
;; by looking at ppss.
- (cond
- ;; Two character opener, LOC at the first character?
- ((/= 0 (logand #x10000 delim-syntax-code))
+ ;; Two character opener, LOC at the first character?
+ (when (/= 0 (logand #x10000 delim-syntax-code))
(/= 0 (logand #x20000 (or (car (syntax-after (1+ loc))) 0))))
- ;; Two character opener, LOC at the second character?
- ((/= 0 (logand #x20000 delim-syntax-code))
- (/= 0 (logand #x10000 (or (car (syntax-after (1- loc))) 0))))
- (t
- nil))))
+ ;; Two character opener, LOC at the second character?
+ (when (/= 0 (logand #x20000 delim-syntax-code))
+ (/= 0 (logand #x10000 (or (car (syntax-after (1- loc))) 0))))))
;; Main function called by font-lock.
(defun rainbow-delimiters--propertize (end)
@@ -222,28 +219,35 @@ Returns t if char at loc meets one of the following conditions:
Used by font-lock for dynamic highlighting."
(let* ((inhibit-point-motion-hooks t)
(last-ppss-pos (point))
- (ppss (syntax-ppss)))
+ (last-ppss (syntax-ppss last-ppss-pos))
+ (last-delim-pos 0))
(while (> end (progn (skip-syntax-forward "^()" end)
(point)))
(let* ((delim-pos (point))
(delim-syntax (syntax-after delim-pos)))
- (setq ppss (parse-partial-sexp last-ppss-pos delim-pos nil nil ppss))
- (setq last-ppss-pos delim-pos)
- ;; `skip-syntax-forward' leaves the point at the delimiter, move past
- ;; it.
- (forward-char)
- (let ((delim-syntax-code (car delim-syntax)))
- (cond
- ((rainbow-delimiters--char-ineligible-p delim-pos ppss delim-syntax-code)
- nil)
- ((= 4 (logand #xFFFF delim-syntax-code))
- ;; The (1+ ...) is needed because `parse-partial-sexp' returns the
- ;; depth at the opening delimiter, not in the block being started.
- (rainbow-delimiters--apply-color delim-pos (1+ (nth 0 ppss)) t))
- (t
- ;; Not an opening delimiter, so it's a closing delimiter.
- (let ((matches-p (eq (cdr delim-syntax) (char-after (nth 1 ppss)))))
- (rainbow-delimiters--apply-color delim-pos (nth 0 ppss) matches-p))))))))
+ (let ((pos-before-delim (1- delim-pos)))
+ (when (and (or (> (- pos-before-delim last-delim-pos) 1)
+ (> (- pos-before-delim last-ppss-pos) 10))
+ (> pos-before-delim last-ppss-pos))
+ (setq last-ppss (parse-partial-sexp last-ppss-pos pos-before-delim nil nil last-ppss))
+ (setq last-ppss-pos pos-before-delim)))
+ (setq last-delim-pos delim-pos)
+ (let ((ppss (parse-partial-sexp last-ppss-pos delim-pos nil nil last-ppss)))
+ ;; `skip-syntax-forward' leaves the point at the delimiter, move past
+ ;; it.
+ (forward-char)
+ (let ((delim-syntax-code (car delim-syntax)))
+ (cond
+ ((rainbow-delimiters--char-ineligible-p delim-pos ppss delim-syntax-code)
+ nil)
+ ((= 4 (logand #xFFFF delim-syntax-code))
+ ;; The (1+ ...) is needed because `parse-partial-sexp' returns the
+ ;; depth at the opening delimiter, not in the block being started.
+ (rainbow-delimiters--apply-color delim-pos (1+ (nth 0 ppss)) t))
+ (t
+ ;; Not an opening delimiter, so it's a closing delimiter.
+ (let ((matches-p (eq (cdr delim-syntax) (char-after (nth 1 ppss)))))
+ (rainbow-delimiters--apply-color delim-pos (nth 0 ppss) matches-p)))))))))
;; We already fontified the delimiters, tell font-lock there's nothing more
;; to do.
nil) |
Suppose we have a language where comments are delimited by
-( … )-
and(+ … +)
, i.e. something likeIt turns out we're highlighting in comments.
The text was updated successfully, but these errors were encountered: