From 145aab0672ae259736ee9230f8e0ff4effa5f4fd Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Sun, 26 Apr 2020 19:30:41 +0100 Subject: [PATCH] cc-mode: add support for Doxygen documentation style * lisp/progmodes/cc-fonts.el (doxygen-font-lock-doc-comments, doxygen-font-lock-keywords): New constants defining Doxygen comment style support. * lisp/progmodes/cc-vars.el (c-doc-comment-style): Updated docstring to mention now-supported Doxygen mode. --- etc/NEWS | 16 +++++++- lisp/progmodes/cc-fonts.el | 78 ++++++++++++++++++++++++++++++++++++++ lisp/progmodes/cc-vars.el | 1 + 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index 8fc23111590..753b7a7fd36 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -198,7 +198,6 @@ like cell phones, tablets or cameras. Previously, assigning a new template to an already defined tag had no effect. - ** map.el *** Pcase 'map' pattern added keyword symbols abbreviation. @@ -288,6 +287,21 @@ prefix on the Subject line in various languages. These new navigation commands are bound to 'n' and 'p' in 'apropos-mode'. +** cc-mode + +*** Added support for Doxygen documentation style. +‘doxygen’ is now valid ‘c-doc-comment-style’ which recognises all +comment styles supported by Doxygen (namely ‘///’, ‘//!’, ‘/** … */’ +and ‘/*! … */’. ‘gtkdoc’ remains the default for C and C++ modes; to +use ‘doxygen’ by default one might evaluate: + + (setq-default c-doc-comment-style + '((java-mode . javadoc) + (pike-mode . autodoc) + (c-mode . doxygen) + (c++-mode . doxygen))) + +or use it in a custom ‘c-style’. * New Modes and Packages in Emacs 28.1 diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 2cbbc66c14f..9ea08a46244 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -3016,6 +3016,84 @@ need for `pike-font-lock-extra-types'.") (c-font-lock-doc-comments "/[*/]!" limit autodoc-font-lock-doc-comments))))) +;; Doxygen + +(defconst doxygen-font-lock-doc-comments + ;; TODO: Handle @code, @verbatim, @dot, @f etc. better by not highlighting + ;; text inside of those commands. Something smarter than just regexes may be + ;; needed to do that efficiently. + `((,(concat + ;; Make sure that the special character has not been escaped. E.g. in + ;; ‘\@foo’ only ‘\@’ is a command (similarly for other characters like + ;; ‘\\foo’, ‘\#%\".|\\\\]" ; single-character escapes + "\\|::\\|---?" ; \:: \-- \--- + "\\)" + ;; HTML tags and entities: + "\\|" + "\\|&\\(?:\\sw+\\|#[0-9]+\\|#x[0-9a-fA-F]+\\);" + "\\)") + 1 ,c-doc-markup-face-name prepend nil) + ;; Commands inside of strings are not commands so override highlighting with + ;; string face. This also affects HTML attribute values if they are + ;; surrounded with double quotes which may or may not be considered a good + ;; thing. + ("\\(?:^\\|[^\\@]\\)\\(\"[^\"[:cntrl:]]+\"\\)" + 1 font-lock-string-face prepend nil) + ;; HTML comments inside of the Doxygen comments. + ("\\(?:^\\|[^\\@]\\)\\(\\)" + 1 font-lock-comment-face prepend nil) + ;; Autolinking. Doxygen auto-links anything that is a class name but we have + ;; no hope of matching those. We are, however, able to match functions and + ;; members using explicit scoped syntax. For functions, we can also find + ;; them by noticing argument-list. Note that Doxygen accepts ‘::’ as well + ;; as ‘#’ as scope operators. + (,(let* ((ref "[\\@]ref\\s-+") + (ref-opt (concat "\\(?:" ref "\\)?")) + (id "[a-zA-Z_][a-zA-Z_0-9]*") + (args "\\(?:()\\|([^()]*)\\)") + (scope "\\(?:#\\|::\\)")) + (concat + "\\(?:^\\|[^\\@/%:]\\)\\(?:" + ref-opt "\\(?1:" scope "?" "\\(?:" id scope "\\)+" "~?" id "\\)" + "\\|" ref-opt "\\(?1:" scope "~?" id "\\)" + "\\|" ref-opt "\\(?1:" scope "?" "~?" id "\\)" args + "\\|" ref "\\(?1:" "~?" id "\\)" + "\\|" ref-opt "\\(?1:~[A-Z][a-zA-Z0-9_]+\\)" + "\\)")) + 1 font-lock-function-name-face prepend nil) + ;; Match URLs and emails. This has two purposes. First of all, Doxygen + ;; autolinks URLs. Second of all, ‘@bar’ in ‘foo@bar.baz’ has been matched + ;; above as a command; try and overwrite it. + (,(let* ((host "[A-Za-z0-9]\\(?:[A-Za-z0-9-]\\{0,61\\}[A-Za-z0-9]\\)") + (fqdn (concat "\\(?:" host "\\.\\)+" host)) + (comp "[!-(*--/-=?-~]+") + (path (concat "/\\(?:" comp "[.]+" "\\)*" comp))) + (concat "\\(?:mailto:\\)?[a-zA-0_.]+@" fqdn + "\\|https?://" fqdn "\\(?:" path "\\)?")) + 0 font-lock-keyword-face prepend nil))) + +(defconst doxygen-font-lock-keywords + `((,(lambda (limit) + (c-font-lock-doc-comments "/\\(?:/[/!]\\|\\*[\\*!]\\)" + limit doxygen-font-lock-doc-comments))))) + ;; 2006-07-10: awk-font-lock-keywords has been moved back to cc-awk.el. (cc-provide 'cc-fonts) diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el index 3995b211854..b885f6ae1d8 100644 --- a/lisp/progmodes/cc-vars.el +++ b/lisp/progmodes/cc-vars.el @@ -576,6 +576,7 @@ comment styles: javadoc -- Javadoc style for \"/** ... */\" comments (default in Java mode). autodoc -- Pike autodoc style for \"//! ...\" comments (default in Pike mode). gtkdoc -- GtkDoc style for \"/** ... **/\" comments (default in C and C++ modes). + doxygen -- Doxygen style. The value may also be a list of doc comment styles, in which case all of them are recognized simultaneously (presumably with markup cues -- 2.39.5