emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master a85befa: Fix Pike Mode's autodoc doc comments style


From: Alan Mackenzie
Subject: [Emacs-diffs] master a85befa: Fix Pike Mode's autodoc doc comments style's continued lines.
Date: Sat, 20 Apr 2019 07:33:59 -0400 (EDT)

branch: master
commit a85befa4aa52033bd6d9927144b358529ec2b360
Author: Alan Mackenzie <address@hidden>
Commit: Alan Mackenzie <address@hidden>

    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.
---
 doc/misc/cc-mode.texi       |   5 ++-
 lisp/progmodes/cc-engine.el |  56 ++++++++++++++++++------
 lisp/progmodes/cc-fonts.el  | 101 +++++++++++++++++++++++++++++++++++++++++---
 lisp/progmodes/cc-mode.el   |  39 +++++++++++++++--
 4 files changed, 177 insertions(+), 24 deletions(-)

diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi
index f73a7fb..6db2c96 100644
--- a/doc/misc/cc-mode.texi
+++ b/doc/misc/cc-mode.texi
@@ -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
address@hidden in @file{cc-fonts.el}.
address@hidden 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}.
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index f0b44d2..80115fb 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -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
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index e7a3748..5832f1f 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -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.
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index fc4ba8f..aea9c7f 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -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



reply via email to

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