emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: font-lock-syntactic-keywords obsolet?


From: Alan Mackenzie
Subject: Re: font-lock-syntactic-keywords obsolet?
Date: Mon, 11 Jul 2016 17:20:16 +0000
User-agent: Mutt/1.5.24 (2015-08-30)

Hello, Dmitry.

On Mon, Jul 11, 2016 at 03:06:30AM +0300, Dmitry Gutov wrote:
> On 07/11/2016 01:11 AM, Alan Mackenzie wrote:

> > There was some code in the mix designed to stop too much expansion of
> > a region when there were humongous macros.  (A few years back somebody
> > had complained about the speed in processing a ~5,000 line macro.)
> > Unfortunately, this code got caught up in raw string processing.  I hope
> > the following patch fixes it.

> It works, thanks.

> Here's a comparatively minor problem: normally, "foo" in the closer has 
> the default face. But if I backspace over the semicolon that follows it, 
> and then type it again, "foo" gets the font-lock-string-face.

> Similarly if I do backspace over and retype the closing double-quote 
> character instead.

Yes.  Thank you for finding these glitches, and sorry I've not been more
careful to find them myself.  Please try out the following patch (as a
supplement to the last one, not a replacement):




diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index dfc2c06..b45686c 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -1542,33 +1542,45 @@ c-font-lock-raw-strings
   ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
   ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
   ;; Fontification".
-  (while (search-forward-regexp
-         "R\\(\"\\)\\([^ ()\\\n\r\t]\\{,16\\}\\)(" limit t)
-    (when
-       (or (and (eobp)
-                (eq (c-get-char-property (1- (point)) 'face)
-                    'font-lock-warning-face))
-           (eq (c-get-char-property (point) 'face) 'font-lock-string-face)
-           (and (equal (c-get-char-property (match-end 2) 'syntax-table) '(1))
-                (equal (c-get-char-property (match-beginning 1) 'syntax-table)
-                       '(1))))
-      (let ((paren-prop (c-get-char-property (1- (point)) 'syntax-table)))
-       (if paren-prop
-           (progn
-             (c-put-font-lock-face (match-beginning 0) (match-end 0)
-                                   'font-lock-warning-face)
-             (when
-                 (and
-                  (equal paren-prop '(15))
-                  (not (c-search-forward-char-property 'syntax-table '(15) 
limit)))
-               (goto-char limit)))
-         (c-put-font-lock-face (match-beginning 1) (match-end 2) 'default)
-         (when (search-forward-regexp
-                (concat ")\\(" (regexp-quote (match-string-no-properties 2))
-                        "\\)\"")
-                limit t)
-           (c-put-font-lock-face (match-beginning 1) (point)
-                                 'default))))))
+  (let* ((state (c-state-semi-pp-to-literal (point)))
+        (string-start (and (eq (cadr state) 'string)
+                           (car (cddr state))))
+        (raw-id (and string-start
+                     (save-excursion
+                       (goto-char string-start)
+                       (and (eq (char-before) ?R)
+                            (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")
+                            (match-string-no-properties 1))))))
+    (while (< (point) limit)
+      (if raw-id
+         (progn
+           (if (search-forward-regexp (concat ")\\(" (regexp-quote raw-id) 
"\\)\"")
+                                      limit 'limit)
+               (c-put-font-lock-face (match-beginning 1) (point) 'default))
+           (setq raw-id nil))
+
+       (when (search-forward-regexp
+              "R\\(\"\\)\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" limit 'limit)
+         (when
+             (or (and (eobp)
+                      (eq (c-get-char-property (1- (point)) 'face)
+                          'font-lock-warning-face))
+                 (eq (c-get-char-property (point) 'face) 
'font-lock-string-face)
+                 (and (equal (c-get-char-property (match-end 2) 'syntax-table) 
'(1))
+                      (equal (c-get-char-property (match-beginning 1) 
'syntax-table)
+                             '(1))))
+           (let ((paren-prop (c-get-char-property (1- (point)) 'syntax-table)))
+             (if paren-prop
+                 (progn
+                   (c-put-font-lock-face (match-beginning 0) (match-end 0)
+                                         'font-lock-warning-face)
+                   (when
+                       (and
+                        (equal paren-prop '(15))
+                        (not (c-search-forward-char-property 'syntax-table 
'(15) limit)))
+                     (goto-char limit)))
+               (c-put-font-lock-face (match-beginning 1) (match-end 2) 
'default)
+               (setq raw-id (match-string-no-properties 2)))))))))
   nil)
 
 (c-lang-defconst c-simple-decl-matchers


> > I know that the processing is currently
> > slow in such a large raw string.  It is probably possible to optimise
> > this.  Whether it is worthwhile is the question.

> I don't know. Probably not if that will involve making the code even 
> more complex.

Optimisation does make code more complicated.  My feeling is that raw
strings of length 1Mbyte are going to be quite rare, and that I should
wait for somebody to complain, first.

> >> I'm confused. If, as we discussed before, syntax properties are applied
> >> in before/after-functions, why does c-font-lock-declarations need to be
> >> concerned with scanning for raw string bounds?

> > The raw string bounds have nothing to do with c-font-lock-declarators.
> > It's just that that function takes a bound which was hardly ever needed,
> > since the function stops when it reaches something which signalled the
> > end of a sequence of declarators (for example, a semicolon).  Hence the
> > fact that the bound given was wrong didn't get noticed.  However, with
> > raw strings in the game, when (point-max) was the bound, the function
> > actually ended up fruitlessly scanning to (point-max) rather than to the
> > `limit' it should have been scanning to.

> > The limit to c-font-lock-declarators is now `(min limit (point-max))'.
> > That way, when the buffer is narrowed to less than `limit', there won't
> > be an out of bounds error, and when there are unterminated raw strings,
> > there won't be useless scanning past `limit' either.

> > I'm not sure if the above will help much, but I hope it does.

> Not sure. That description sounds like it's about performance, and not 
> about correctness.

Well, giving the correct bound improves the performance.  Let's leave it
at that.

> Since you're only mentioning scanning forward, that doesn't seem to
> account for problems with when I'm fiddling with the closing
> delimiter.

No, they're two unrelated things.

-- 
Alan Mackenzie (Nuremberg, Germany).



reply via email to

[Prev in Thread] Current Thread [Next in Thread]