[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).