mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-30 04:10:54 -08:00
CC Mode. Fix fontification bug with unterminated quotes on adjacent lines
In particular, with these unterminated quotes on each of two adjacent lines, the following text was spuriously fontified with string face. * lisp/progmodes/cc-defs.el (c-search-backward-char-property-with-value-on-char): New macro. * lisp/progmodes/cc-mode.el (c-clear-string-fences): Check whether there is an unmatched quote at a lower buffer position which should match the current quote, rather than wrongly assuming the latter is unmatched and marking it with a punctuation syntax. (c-font-lock-fontify-region): Ensure all pertinent parts of the buffer have string fence properties applied before performing any syntactic operations on it; in particular, this applies to a quote at an earlier buffer position which "matches" one inside the region about to be fontified.
This commit is contained in:
parent
3c278b4999
commit
757e66afdc
2 changed files with 95 additions and 38 deletions
|
|
@ -1340,6 +1340,29 @@ nil; point is then left undefined."
|
|||
(search-forward-regexp "\\(\n\\|.\\)") ; to set the match-data.
|
||||
(point))))
|
||||
|
||||
(defmacro c-search-backward-char-property-with-value-on-char
|
||||
(property value char &optional limit)
|
||||
"Search backward for a text-property PROPERTY having value VALUE on a
|
||||
character with value CHAR.
|
||||
LIMIT bounds the search. The value comparison is done with `equal'.
|
||||
PROPERTY must be a constant.
|
||||
|
||||
Leave point just before the character, and set the match data on
|
||||
this character, and return point. If the search fails, return
|
||||
nil; point is then left undefined."
|
||||
`(let ((char-skip (concat "^" (char-to-string ,char)))
|
||||
(-limit- (or ,limit (point-min)))
|
||||
(-value- ,value))
|
||||
(while
|
||||
(and
|
||||
(progn (skip-chars-backward char-skip -limit-)
|
||||
(> (point) -limit-))
|
||||
(not (equal (c-get-char-property (1- (point)) ,property) -value-)))
|
||||
(backward-char))
|
||||
(when (> (point) -limit-)
|
||||
(search-backward-regexp "\\(\n\\|.\\)") ; to set the match-data.
|
||||
(point))))
|
||||
|
||||
(defmacro c-search-forward-char-property-without-value-on-char
|
||||
(property value char &optional limit)
|
||||
"Search forward for a character CHAR without text property PROPERTY having
|
||||
|
|
|
|||
|
|
@ -1233,6 +1233,15 @@ Note that the style variables are always made local to the buffer."
|
|||
;; Check we haven't left any unbalanced "s.
|
||||
(save-excursion
|
||||
(setq pos beg)
|
||||
;; Is there already an unbalanced " before BEG?
|
||||
(setq pos (c-min-property-position pos end 'c-fl-syn-tab))
|
||||
(when (< pos end) (goto-char pos))
|
||||
(when (and (save-match-data
|
||||
(c-search-backward-char-property-with-value-on-char
|
||||
'c-fl-syn-tab '(15) ?\"
|
||||
(max (- (point) 500) (point-min))))
|
||||
(not (equal (c-get-char-property (point) 'syntax-table) '(1))))
|
||||
(setq pos (1+ pos)))
|
||||
(while (< pos end)
|
||||
(setq pos
|
||||
(c-min-property-position pos end 'c-fl-syn-tab))
|
||||
|
|
@ -2234,44 +2243,69 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
|
|||
;; line was fouled up by context fontification.
|
||||
(save-restriction
|
||||
(widen)
|
||||
(let (new-beg new-end new-region case-fold-search)
|
||||
(if (and c-in-after-change-fontification
|
||||
(< beg c-new-END) (> end c-new-BEG))
|
||||
;; Region and the latest after-change fontification region overlap.
|
||||
;; Determine the upper and lower bounds of our adjusted region
|
||||
;; separately.
|
||||
(progn
|
||||
(if (<= beg c-new-BEG)
|
||||
(setq c-in-after-change-fontification nil))
|
||||
(setq new-beg
|
||||
(if (and (>= beg (c-point 'bol c-new-BEG))
|
||||
(<= beg c-new-BEG))
|
||||
;; Either jit-lock has accepted `c-new-BEG', or has
|
||||
;; (probably) extended the change region spuriously to
|
||||
;; BOL, which position likely has a syntactically
|
||||
;; different position. To ensure correct fontification,
|
||||
;; we start at `c-new-BEG', assuming any characters to the
|
||||
;; left of `c-new-BEG' on the line do not require
|
||||
;; fontification.
|
||||
c-new-BEG
|
||||
(setq new-region (c-before-context-fl-expand-region beg end)
|
||||
new-end (cdr new-region))
|
||||
(car new-region)))
|
||||
(setq new-end
|
||||
(if (and (>= end (c-point 'bol c-new-END))
|
||||
(<= end c-new-END))
|
||||
c-new-END
|
||||
(or new-end
|
||||
(cdr (c-before-context-fl-expand-region beg end))))))
|
||||
;; Context (etc.) fontification.
|
||||
(setq new-region (c-before-context-fl-expand-region beg end)
|
||||
new-beg (car new-region) new-end (cdr new-region)))
|
||||
(c-save-buffer-state nil
|
||||
(unwind-protect
|
||||
(progn (c-restore-string-fences new-beg new-end)
|
||||
(funcall (default-value 'font-lock-fontify-region-function)
|
||||
new-beg new-end verbose))
|
||||
(c-clear-string-fences))))))
|
||||
(let (new-beg new-end new-region case-fold-search string-fence-beg lim)
|
||||
;; Check how far back we need to extend the region where we reapply the
|
||||
;; string fence syntax-table properties. These must be in place for the
|
||||
;; coming fontification operations.
|
||||
(save-excursion
|
||||
(goto-char (if c-in-after-change-fontification
|
||||
(min beg c-new-BEG)
|
||||
beg))
|
||||
(setq lim (max (- (point) 500) (point-min)))
|
||||
(while
|
||||
(progn
|
||||
(skip-chars-backward "^\"" lim)
|
||||
(or (bobp) (backward-char))
|
||||
(save-excursion
|
||||
(eq (logand (skip-chars-backward "\\\\") 1) 1))))
|
||||
(setq string-fence-beg
|
||||
(cond ((c-get-char-property (point) 'c-fl-syn-tab)
|
||||
(point))
|
||||
(c-in-after-change-fontification
|
||||
c-new-BEG)
|
||||
(t beg)))
|
||||
(c-save-buffer-state nil
|
||||
;; Temporarily reapply the string fence syntax-table properties.
|
||||
(c-with-extended-string-fences
|
||||
string-fence-beg (if c-in-after-change-fontification
|
||||
(max end c-new-END)
|
||||
end)
|
||||
|
||||
(if (and c-in-after-change-fontification
|
||||
(< beg c-new-END) (> end c-new-BEG))
|
||||
;; Region and the latest after-change fontification region overlap.
|
||||
;; Determine the upper and lower bounds of our adjusted region
|
||||
;; separately.
|
||||
(progn
|
||||
(if (<= beg c-new-BEG)
|
||||
(setq c-in-after-change-fontification nil))
|
||||
(setq new-beg
|
||||
(if (and (>= beg (c-point 'bol c-new-BEG))
|
||||
(<= beg c-new-BEG))
|
||||
;; Either jit-lock has accepted `c-new-BEG', or has
|
||||
;; (probably) extended the change region spuriously
|
||||
;; to BOL, which position likely has a
|
||||
;; syntactically different position. To ensure
|
||||
;; correct fontification, we start at `c-new-BEG',
|
||||
;; assuming any characters to the left of
|
||||
;; `c-new-BEG' on the line do not require
|
||||
;; fontification.
|
||||
c-new-BEG
|
||||
(setq new-region (c-before-context-fl-expand-region beg end)
|
||||
new-end (cdr new-region))
|
||||
(car new-region)))
|
||||
(setq new-end
|
||||
(if (and (>= end (c-point 'bol c-new-END))
|
||||
(<= end c-new-END))
|
||||
c-new-END
|
||||
(or new-end
|
||||
(cdr (c-before-context-fl-expand-region beg end))))))
|
||||
;; Context (etc.) fontification.
|
||||
(setq new-region (c-before-context-fl-expand-region beg end)
|
||||
new-beg (car new-region) new-end (cdr new-region)))
|
||||
;; Finally invoke font lock's functionality.
|
||||
(funcall (default-value 'font-lock-fontify-region-function)
|
||||
new-beg new-end verbose)))))))
|
||||
|
||||
(defun c-after-font-lock-init ()
|
||||
;; Put on `font-lock-mode-hook'. This function ensures our after-change
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue