summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2019-11-09 12:09:30 +0000
committerAlan Mackenzie <acm@muc.de>2019-11-09 12:09:30 +0000
commitb293aa91bcc7f553ffbc6c67027f3c86d06ffbd7 (patch)
tree39f019da4ce7a41d1367c01f590487b529bad2a3 /lisp
parent6daa80d04e575a27f53f60f5fafd7fcba39b4b2a (diff)
downloademacs-b293aa91bcc7f553ffbc6c67027f3c86d06ffbd7.tar.gz
CC Mode. Allow fontification of "wrong" style comments with warning face.
This fixes bug #4192. * etc/NEWS: Add a new entry. * lisp/progmodes/cc-defs.el (c-font-lock-flush): New macro. * lisp/progmodes/cc-cmds.el (c-toggle-comment-style): On toggling the comment style, invoke c-font-lock-flush when c-mark-wrong-style-of-comment is non-nil, to cause that marking to be done instead on the other style of comment. * lisp/progmodes/cc-fonts.el (c-maybe-font-lock-wrong-style-comments): New function. (c-cpp-matchers): Call c-maybe-font-lock-wrong-style-comments when appropriate. * lisp/progmodes/cc-vars.el (c-mark-wrong-style-of-comment): New customizable option. * doc/misc/cc-mode.texi (top level, Indentation Commands, Guessing the Style, Custom Macros): For some opening quote marks, correct '' to ``. (Minor Modes): Add an xref to the new page "Wrong Comment Style" in a footnote. (Wrong Comment Style): New page.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/progmodes/cc-cmds.el10
-rw-r--r--lisp/progmodes/cc-defs.el7
-rw-r--r--lisp/progmodes/cc-fonts.el61
-rw-r--r--lisp/progmodes/cc-vars.el8
4 files changed, 85 insertions, 1 deletions
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 9aa2019ae60..af2efb63fc3 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -391,6 +391,16 @@ This action does nothing when the mode only has one comment style."
(if c-block-comment-flag
(concat " " c-block-comment-ender)
""))
+ ;; If necessary, invert the sense of fontification of wrong style comments.
+ (when (and c-mark-wrong-style-of-comment
+ font-lock-mode
+ c-block-comment-starter
+ c-block-comment-ender)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (c-font-lock-flush (point-min) (point-max)))))
(c-update-modeline)
(c-keep-region-active))
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index e9a3e16db36..6a9371e6f19 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -219,6 +219,13 @@ This variant works around bugs in `eval-when-compile' in various
`(cl-delete-duplicates ,cl-seq ,@cl-keys)
`(delete-duplicates ,cl-seq ,@cl-keys))))
+(defmacro c-font-lock-flush (beg end)
+ "Declare the region BEG...END's fontification as out-of-date.
+On XEmacs and older Emacsen, this refontifies that region immediately."
+ (if (fboundp 'font-lock-flush)
+ `(font-lock-flush ,beg ,end)
+ `(font-lock-fontify-region ,beg ,end)))
+
(defmacro c-point (position &optional point)
"Return the value of certain commonly referenced POSITIONs relative to POINT.
The current point is used if POINT isn't specified. POSITION can be
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index c27b70603ed..0daea8c84c9 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -95,6 +95,7 @@
;; during compilation.
(cc-bytecomp-defvar c-preprocessor-face-name)
(cc-bytecomp-defvar c-reference-face-name)
+(cc-bytecomp-defvar c-block-comment-flag)
(cc-bytecomp-defun c-fontify-recorded-types-and-refs)
(cc-bytecomp-defun c-font-lock-declarators)
(cc-bytecomp-defun c-font-lock-objc-method)
@@ -532,7 +533,12 @@ stuff. Used on level 1 and higher."
(sws-depth (c-lang-const c-syntactic-ws-depth))
(nsws-depth (c-lang-const c-nonempty-syntactic-ws-depth)))
- `(;; The stuff after #error and #warning is a message, so
+ `(;; Fontify "invalid" comment delimiters
+ ,@(when (and (c-lang-const c-block-comment-starter)
+ (c-lang-const c-line-comment-starter))
+ `(c-maybe-font-lock-wrong-style-comments))
+
+ ;; The stuff after #error and #warning is a message, so
;; fontify it as a string.
,@(when (c-lang-const c-cpp-message-directives)
(let* ((re (c-make-keywords-re 'appendable ; nil
@@ -715,6 +721,59 @@ stuff. Used on level 1 and higher."
(parse-partial-sexp end limit nil nil state 'syntax-table)))
nil)
+(defun c-maybe-font-lock-wrong-style-comments (limit)
+ ;; This function will be called from font-lock-for a region bounded by POINT
+ ;; and LIMIT, as though it were to identify a keyword for
+ ;; font-lock-keyword-face. It always returns NIL to inhibit this and
+ ;; prevent a repeat invocation. See elisp/lispref page "Search-based
+ ;; Fontification".
+ ;;
+ ;; This function fontifies "invalid" comment delimiters with
+ ;; `font-lock-warning-face'. A delimiter is "invalid" when
+ ;; `c-mark-wrong-style-of-comment' is non-nil, and the delimiter style is
+ ;; not the default specified by `c-block-comment-flag'.
+ (when c-mark-wrong-style-of-comment
+ (let* ((lit (c-semi-pp-to-literal (point)))
+ (s (car lit)) ; parse-partial-sexp state.
+ )
+ ;; First, deal with and move out of any literal we start in.
+ (cond
+ ((null (cadr lit))) ; Not in a literal
+ ((eq (cadr lit) 'string)
+ (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table)))
+ ((and (not c-block-comment-flag) ; In an "invalid" block comment
+ (eq (cadr lit) 'c))
+ (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table))
+ ;; Font lock the block comment ender with warning face.
+ (when (not (nth 4 s))
+ (c-put-font-lock-face (- (point) (length c-block-comment-ender))
+ (point) font-lock-warning-face)))
+ (t ; In a line comment, or a "valid" block comment
+ (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table))))
+
+ (while (< (point) limit)
+ (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table))
+ (cond
+ ((or (nth 3 s) ; In a string
+ (and (nth 4 s) ; In a comment
+ (eq (nth 7 s) ; Comment style
+ (if c-block-comment-flag
+ nil ; Block comment
+ 1)))) ; Line comment
+ ;; Move over a "valid" literal.
+ (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table)))
+ ((nth 4 s) ; In an invalid comment
+ ;; Fontify the invalid comment opener.
+ (c-put-font-lock-face (nth 8 s) (point) font-lock-warning-face)
+ ;; Move to end of comment or LIMIT.
+ (setq s (parse-partial-sexp (point) limit nil nil s 'syntax-table))
+ ;; Fontify an invalid block comment ender, if that's what we have.
+ (when (and (not c-block-comment-flag)
+ (not (nth 4 s))) ; We're outside the comment
+ (c-put-font-lock-face (- (point) (length c-block-comment-ender))
+ (point) font-lock-warning-face)))))))
+ nil)
+
(c-lang-defconst c-basic-matchers-before
"Font lock matchers for basic keywords, labels, references and various
other easily recognizable things that should be fontified before generic
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index 60ad42f24f4..273174e0413 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -1751,6 +1751,14 @@ variables.")
c-macro-names-with-semicolon: %s"
c-macro-names-with-semicolon))))))
+(defcustom c-mark-wrong-style-of-comment nil
+ "Fontify \"invalid\" comment delims with `font-lock-warning-face' if non-nil.
+\"Invalid\" means a line comment when the default comment style (set by
+`c-toggle-comment-style') is block, or a block comment otherwise."
+ :type 'boolean
+ :group 'c
+ :version 27.1)
+
(defvar c-file-style nil
"Variable interface for setting style via File Local Variables.
In a file's Local Variable section, you can set this variable to a