mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-23 07:19:15 +00:00
Fix Pike Mode's autodoc doc comments style's continued lines.
* lisp/progmodes/cc-engine.el (c-forward-sws, c-backward-sws): Recognize matches of c-doc-line-join-re as syntactic whitespace. (c-find-decl-prefix-search): Recognize and move over matches of c-doc-line-join-re as whitespace. (c-find-decl-spots): Before moving backward a char, check (bobp). Before moving forward over a comment, check it isn't possibly a "bright" comment. * lisp/progmodes/cc-fonts.el (c-get-doc-comment-style): New function, extracted from c-compose-keywords-list. (c-compose-keywords-list): Call the above new function. (pike-font-lock-keywords, pike-font-lock-keywords-2) (pike-font-lock-keywords-3): Call c-set-doc-comment-res. (c-doc-line-join-re, c-doc-bright-comment-start-re, c-doc-line-join-end-ch): New variables. (c-set-doc-comment-re-element, c-set-doc-comment-char-list): New macros. (c-set-doc-comment-res): New function. (c-font-lock-doc-comments): For consistency and repeatability, in a sequence of C++ style doc comments, don't fontify the region between BOL and the comment marker. (autodoc-line-join-re, autodoc-bright-comment-start-re) (autodoc-line-join-end-ch): New variables. * lisp/progmodes/cc-mode.el (c-doc-fl-decl-start, c-doc-fl-decl-end): New functions. (c-change-expand-fl-region, c-context-expand-fl-region): Call the above two new functions for extra possibilities for the start and end of a construct. * doc/misc/cc-mode.texi (Doc Comments): Add a sentence drawing attention to the possibility of fontifying constructs within a doc comment.
This commit is contained in:
parent
6f334b6bc0
commit
a85befa4aa
@ -2140,7 +2140,10 @@ with @code{c-doc-comment-style}: Supply a variable or function
|
||||
in @code{c-doc-comment-style}. If it's a variable, it's prepended to
|
||||
@code{font-lock-keywords}. If it's a function, it's called at mode
|
||||
initialization and the result is prepended. For an example, see
|
||||
@code{javadoc-font-lock-keywords} in @file{cc-fonts.el}.
|
||||
@code{javadoc-font-lock-keywords} in @file{cc-fonts.el}. It is even
|
||||
possible, to a limited extent, to fontify constructs inside a doc
|
||||
comment with other faces. For an example, see pike autodoc comment
|
||||
style towards the end of @file{cc-fonts-el}.
|
||||
|
||||
If you add support for another doc comment style, please consider
|
||||
contributing it: send a note to @email{bug-cc-mode@@gnu.org}.
|
||||
|
@ -152,6 +152,10 @@
|
||||
(cc-require-when-compile 'cc-langs)
|
||||
(cc-require 'cc-vars)
|
||||
|
||||
(defvar c-doc-line-join-re)
|
||||
(defvar c-doc-bright-comment-start-re)
|
||||
(defvar c-doc-line-join-end-ch)
|
||||
|
||||
|
||||
;; Make declarations for all the `c-lang-defvar' variables in cc-langs.
|
||||
|
||||
@ -1930,7 +1934,8 @@ comment at the start of cc-engine.el for more info."
|
||||
(skip-chars-forward " \t\n\r\f\v")
|
||||
(when (or (looking-at c-syntactic-ws-start)
|
||||
(and c-opt-cpp-prefix
|
||||
(looking-at c-noise-macro-name-re)))
|
||||
(looking-at c-noise-macro-name-re))
|
||||
(looking-at c-doc-line-join-re))
|
||||
|
||||
(setq rung-end-pos (min (1+ (point)) (point-max)))
|
||||
(if (setq rung-is-marked (text-property-any rung-pos rung-end-pos
|
||||
@ -2060,6 +2065,13 @@ comment at the start of cc-engine.el for more info."
|
||||
(looking-at c-noise-macro-name-re))
|
||||
;; Skip over a noise macro.
|
||||
(goto-char (match-end 1))
|
||||
(not (eobp)))
|
||||
|
||||
((looking-at c-doc-line-join-re)
|
||||
;; Skip over a line join in (e.g.) Pike autodoc.
|
||||
(goto-char (match-end 0))
|
||||
(setq safe-start nil) ; Never cache this; the doc style could be
|
||||
; changed at any time.
|
||||
(not (eobp)))))
|
||||
|
||||
;; We've searched over a piece of non-white syntactic ws. See if this
|
||||
@ -2154,7 +2166,8 @@ comment at the start of cc-engine.el for more info."
|
||||
(let (;; `rung-pos' is set to a position as late as possible in the unmarked
|
||||
;; part of the simple ws region.
|
||||
(rung-pos (point)) next-rung-pos last-put-in-sws-pos
|
||||
rung-is-marked simple-ws-beg cmt-skip-pos)
|
||||
rung-is-marked simple-ws-beg cmt-skip-pos
|
||||
(doc-line-join-here (concat c-doc-line-join-re "\\=")))
|
||||
|
||||
;; Skip simple horizontal ws and do a quick check on the preceding
|
||||
;; character to see if it's anything that can't end syntactic ws, so we can
|
||||
@ -2164,12 +2177,17 @@ comment at the start of cc-engine.el for more info."
|
||||
(skip-chars-backward " \t\f")
|
||||
(when (and (not (bobp))
|
||||
(save-excursion
|
||||
(backward-char)
|
||||
(or (looking-at c-syntactic-ws-end)
|
||||
(and c-opt-cpp-prefix
|
||||
(looking-at c-symbol-char-key)
|
||||
(progn (c-beginning-of-current-token)
|
||||
(looking-at c-noise-macro-name-re))))))
|
||||
(or (and
|
||||
(memq (char-before) c-doc-line-join-end-ch) ; For speed.
|
||||
(re-search-backward doc-line-join-here
|
||||
(c-point 'bopl) t))
|
||||
(progn
|
||||
(backward-char)
|
||||
(or (looking-at c-syntactic-ws-end)
|
||||
(and c-opt-cpp-prefix
|
||||
(looking-at c-symbol-char-key)
|
||||
(progn (c-beginning-of-current-token)
|
||||
(looking-at c-noise-macro-name-re))))))))
|
||||
;; Try to find a rung position in the simple ws preceding point, so that
|
||||
;; we can get a cache hit even if the last bit of the simple ws has
|
||||
;; changed recently.
|
||||
@ -2309,7 +2327,11 @@ comment at the start of cc-engine.el for more info."
|
||||
(looking-at c-noise-macro-name-re)))))
|
||||
;; Skipped over a noise macro
|
||||
(goto-char next-rung-pos)
|
||||
t)))
|
||||
t)
|
||||
|
||||
((and
|
||||
(memq (char-before) c-doc-line-join-end-ch) ; For speed.
|
||||
(re-search-backward doc-line-join-here (c-point 'bopl) t)))))
|
||||
|
||||
;; We've searched over a piece of non-white syntactic ws. See if this
|
||||
;; can be cached.
|
||||
@ -5691,7 +5713,16 @@ comment at the start of cc-engine.el for more info."
|
||||
|
||||
(when (< cfd-match-pos cfd-limit)
|
||||
;; Skip forward past comments only so we don't skip macros.
|
||||
(c-forward-comments)
|
||||
(while
|
||||
(progn
|
||||
(c-forward-comments)
|
||||
;; The following is of use within a doc comment when a doc
|
||||
;; comment style has removed face properties from a construct,
|
||||
;; and is relying on `c-font-lock-declarations' to add them
|
||||
;; again.
|
||||
(and (< (point) cfd-limit)
|
||||
(looking-at c-doc-line-join-re)
|
||||
(goto-char (match-end 0)))))
|
||||
;; Set the position to continue at. We can avoid going over
|
||||
;; the comments skipped above a second time, but it's possible
|
||||
;; that the comment skipping has taken us past `cfd-prop-match'
|
||||
@ -5950,7 +5981,7 @@ comment at the start of cc-engine.el for more info."
|
||||
(goto-char (or start-in-literal cfd-start-pos))
|
||||
;; The only syntactic ws in macros are comments.
|
||||
(c-backward-comments)
|
||||
(backward-char)
|
||||
(or (bobp) (backward-char))
|
||||
(c-beginning-of-current-token))
|
||||
|
||||
(start-in-literal
|
||||
@ -5975,7 +6006,8 @@ comment at the start of cc-engine.el for more info."
|
||||
(not (eq (c-get-char-property (point) 'c-type)
|
||||
'c-decl-end))))))
|
||||
|
||||
(when (= (point) start-in-literal)
|
||||
(when (and (= (point) start-in-literal)
|
||||
(not (looking-at c-doc-bright-comment-start-re)))
|
||||
;; Didn't find any property inside the comment, so we can
|
||||
;; skip it entirely. (This won't skip past a string, but
|
||||
;; that'll be handled quickly by the next
|
||||
|
@ -2089,6 +2089,14 @@ higher."
|
||||
(c-lang-const c-complex-decl-matchers)
|
||||
(c-lang-const c-basic-matchers-after)))
|
||||
|
||||
(defun c-get-doc-comment-style ()
|
||||
;; Get the symbol (or list of symbols) constituting the document style.
|
||||
;; Return nil if there is no such, otherwise something like `autodoc'.
|
||||
(if (consp (car-safe c-doc-comment-style))
|
||||
(cdr-safe (or (assq c-buffer-is-cc-mode c-doc-comment-style)
|
||||
(assq 'other c-doc-comment-style)))
|
||||
c-doc-comment-style))
|
||||
|
||||
(defun c-compose-keywords-list (base-list)
|
||||
;; Incorporate the font lock keyword lists according to
|
||||
;; `c-doc-comment-style' on the given keyword list and return it.
|
||||
@ -2099,11 +2107,7 @@ higher."
|
||||
(unless (memq c-doc-face-name c-literal-faces)
|
||||
(setq c-literal-faces (cons c-doc-face-name c-literal-faces)))
|
||||
|
||||
(let* ((doc-keywords
|
||||
(if (consp (car-safe c-doc-comment-style))
|
||||
(cdr-safe (or (assq c-buffer-is-cc-mode c-doc-comment-style)
|
||||
(assq 'other c-doc-comment-style)))
|
||||
c-doc-comment-style))
|
||||
(let* ((doc-keywords (c-get-doc-comment-style))
|
||||
(list (nconc (c--mapcan
|
||||
(lambda (doc-style)
|
||||
(let ((sym (intern
|
||||
@ -2552,15 +2556,88 @@ need for `pike-font-lock-extra-types'.")
|
||||
"Default expressions to highlight in Pike mode.")
|
||||
|
||||
(defun pike-font-lock-keywords-2 ()
|
||||
(c-set-doc-comment-res)
|
||||
(c-compose-keywords-list pike-font-lock-keywords-2))
|
||||
(defun pike-font-lock-keywords-3 ()
|
||||
(c-set-doc-comment-res)
|
||||
(c-compose-keywords-list pike-font-lock-keywords-3))
|
||||
(defun pike-font-lock-keywords ()
|
||||
(c-set-doc-comment-res)
|
||||
(c-compose-keywords-list pike-font-lock-keywords))
|
||||
|
||||
|
||||
;;; Doc comments.
|
||||
|
||||
(defvar c-doc-line-join-re "a\\`")
|
||||
;; Matches a join of two lines in a doc comment.
|
||||
;; This should not be changed directly, but instead set by
|
||||
;; `c-setup-doc-comment-style'. This variable is used in `c-find-decl-spots'
|
||||
;; in (e.g.) autodoc style comments to bridge the gap between a "@\n" at an
|
||||
;; EOL and the token following "//!" on the next line.
|
||||
|
||||
(defvar c-doc-bright-comment-start-re "a\\`")
|
||||
;; Matches the start of a "bright" comment, one whose contents may be
|
||||
;; fontified by, e.g., `c-font-lock-declarations'.
|
||||
|
||||
(defvar c-doc-line-join-end-ch nil)
|
||||
;; A list of characters, each being a last character of a doc comment marker,
|
||||
;; e.g. the ! from pike autodoc's "//!".
|
||||
|
||||
(defmacro c-set-doc-comment-re-element (suffix)
|
||||
;; Set the variable `c-doc-line-join-re' to a buffer local value suitable
|
||||
;; for the current doc comment style, or kill the local value.
|
||||
(let ((var (intern (concat "c-doc" suffix))))
|
||||
`(let* ((styles (c-get-doc-comment-style))
|
||||
elts)
|
||||
(when (atom styles)
|
||||
(setq styles (list styles)))
|
||||
(setq elts
|
||||
(mapcar (lambda (style)
|
||||
(let ((sym
|
||||
(intern-soft
|
||||
(concat (symbol-name style) ,suffix))))
|
||||
(and sym
|
||||
(boundp sym)
|
||||
(symbol-value sym))))
|
||||
styles))
|
||||
(setq elts (delq nil elts))
|
||||
(setq elts (and elts
|
||||
(concat "\\("
|
||||
(mapconcat #'identity elts "\\|")
|
||||
"\\)")))
|
||||
(if elts
|
||||
(set (make-local-variable ',var) elts)
|
||||
(kill-local-variable ',var)))))
|
||||
|
||||
(defmacro c-set-doc-comment-char-list (suffix)
|
||||
;; Set the variable 'c-doc-<suffix>' to the list of *-<suffix>, which must
|
||||
;; be characters, and * represents the doc comment style.
|
||||
(let ((var (intern (concat "c-doc" suffix))))
|
||||
`(let* ((styles (c-get-doc-comment-style))
|
||||
elts)
|
||||
(when (atom styles)
|
||||
(setq styles (list styles)))
|
||||
(setq elts
|
||||
(mapcar (lambda (style)
|
||||
(let ((sym
|
||||
(intern-soft
|
||||
(concat (symbol-name style) ,suffix))))
|
||||
(and sym
|
||||
(boundp sym)
|
||||
(symbol-value sym))))
|
||||
styles))
|
||||
(setq elts (delq nil elts))
|
||||
(if elts
|
||||
(set (make-local-variable ',var) elts)
|
||||
(kill-local-variable ',var)))))
|
||||
|
||||
(defun c-set-doc-comment-res ()
|
||||
;; Set the variables `c-doc-line-join-re' and
|
||||
;; `c-doc-bright-comment-start-re' from the current doc comment style(s).
|
||||
(c-set-doc-comment-re-element "-line-join-re")
|
||||
(c-set-doc-comment-re-element "-bright-comment-start-re")
|
||||
(c-set-doc-comment-char-list "-line-join-end-ch"))
|
||||
|
||||
(defun c-font-lock-doc-comments (prefix limit keywords)
|
||||
;; Fontify the comments between the point and LIMIT whose start
|
||||
;; matches PREFIX with `c-doc-face-name'. Assumes comments have been
|
||||
@ -2621,17 +2698,20 @@ need for `pike-font-lock-extra-types'.")
|
||||
(goto-char comment-beg)
|
||||
(while (and (progn
|
||||
(c-forward-single-comment)
|
||||
(c-put-font-lock-face comment-beg (point)
|
||||
c-doc-face-name)
|
||||
(skip-syntax-forward " ")
|
||||
(setq comment-beg (point))
|
||||
(< (point) limit))
|
||||
(looking-at prefix))))
|
||||
(goto-char comment-beg)
|
||||
(c-forward-single-comment))
|
||||
(c-forward-single-comment)
|
||||
(c-put-font-lock-face comment-beg (point) c-doc-face-name))
|
||||
(if (> (point) limit) (goto-char limit))
|
||||
(setq comment-beg nil)
|
||||
|
||||
(let ((region-end (point))
|
||||
(keylist keywords) keyword matcher highlights)
|
||||
(c-put-font-lock-face region-beg region-end c-doc-face-name)
|
||||
(save-restriction
|
||||
;; Narrow to the doc comment. Among other things, this
|
||||
;; helps by making "^" match at the start of the comment.
|
||||
@ -2838,6 +2918,13 @@ need for `pike-font-lock-extra-types'.")
|
||||
0 'font-lock-warning-face prepend nil)
|
||||
))
|
||||
|
||||
(defconst autodoc-line-join-re "@[\n\r][ \t]*/[/*]!")
|
||||
;; Matches a line continuation in autodoc comment style.
|
||||
(defconst autodoc-bright-comment-start-re "/[/*]!")
|
||||
;; Matches an autodoc comment opener.
|
||||
(defconst autodoc-line-join-end-ch ?!)
|
||||
;; The final character of `autodoc-line-join-re'.
|
||||
|
||||
(defun autodoc-font-lock-keywords ()
|
||||
;; Note that we depend on that `c-current-comment-prefix' has got
|
||||
;; its proper value here.
|
||||
|
@ -1797,6 +1797,34 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
|
||||
(funcall fn beg end old-len))
|
||||
c-before-font-lock-functions)))))))
|
||||
|
||||
(defun c-doc-fl-decl-start (pos)
|
||||
;; If the line containing POS is in a doc comment continued line (as defined
|
||||
;; by `c-doc-line-join-re'), return the position of the first line of the
|
||||
;; sequence. Otherwise, return nil. Point has no significance at entry to
|
||||
;; and exit from this function.
|
||||
(goto-char pos)
|
||||
(back-to-indentation)
|
||||
(and (or (looking-at c-comment-start-regexp)
|
||||
(memq (c-literal-type (c-literal-limits)) '(c c++)))
|
||||
(progn
|
||||
(end-of-line)
|
||||
(let ((here (point)))
|
||||
(while (re-search-backward c-doc-line-join-re (c-point 'bopl) t))
|
||||
(and (not (eq (point) here))
|
||||
(c-point 'bol))))))
|
||||
|
||||
(defun c-doc-fl-decl-end (pos)
|
||||
;; If the line containing POS is continued by a doc comment continuation
|
||||
;; marker (as defined by `c-doc-line-join-re), return the position of
|
||||
;; the BOL at the end of the sequence. Otherwise, return nil. Point has no
|
||||
;; significance at entry to and exit from this function.
|
||||
(goto-char pos)
|
||||
(back-to-indentation)
|
||||
(let ((here (point)))
|
||||
(while (re-search-forward c-doc-line-join-re (c-point 'eonl) t))
|
||||
(and (not (eq (point) here))
|
||||
(c-point 'bonl))))
|
||||
|
||||
(defun c-fl-decl-start (pos)
|
||||
;; If the beginning of the line containing POS is in the middle of a "local"
|
||||
;; declaration, return the beginning of that declaration. Otherwise return
|
||||
@ -1912,9 +1940,10 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
|
||||
;; and OLD-LEN are not used.
|
||||
(if font-lock-mode
|
||||
(setq c-new-BEG
|
||||
(or (c-fl-decl-start c-new-BEG) (c-point 'bol c-new-BEG))
|
||||
(or (c-fl-decl-start c-new-BEG) (c-doc-fl-decl-start c-new-BEG)
|
||||
(c-point 'bol c-new-BEG))
|
||||
c-new-END
|
||||
(or (c-fl-decl-end c-new-END)
|
||||
(or (c-fl-decl-end c-new-END) (c-doc-fl-decl-end c-new-END)
|
||||
(c-point 'bonl c-new-END)))))
|
||||
|
||||
(defun c-context-expand-fl-region (beg end)
|
||||
@ -1922,8 +1951,10 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
|
||||
;; "local" declaration containing BEG (see `c-fl-decl-start') or BOL BEG is
|
||||
;; in. NEW-END is beginning of the line after the one END is in.
|
||||
(c-save-buffer-state ()
|
||||
(cons (or (c-fl-decl-start beg) (c-point 'bol beg))
|
||||
(or (c-fl-decl-end end) (c-point 'bonl (1- end))))))
|
||||
(cons (or (c-fl-decl-start beg) (c-doc-fl-decl-start beg)
|
||||
(c-point 'bol beg))
|
||||
(or (c-fl-decl-end end) (c-doc-fl-decl-end end)
|
||||
(c-point 'bonl (1- end))))))
|
||||
|
||||
(defun c-before-context-fl-expand-region (beg end)
|
||||
;; Expand the region (BEG END) as specified by
|
||||
|
Loading…
Reference in New Issue
Block a user