12

For the following C++ function:

bool importantStuff(double a, double b);

It should output the following snippet, perhaps without the tags:

/**
 * <Insert description of importantStuff>
 *
 * @param a <Insert description of a>
 * @param b <Insert description of b>
 * @return <Insert description of the return value>
 */

I've looked around the net, but the closest I've gotten to an answer is this old SO question where the answer depends on the no longer maintained doxymacs mode.

Rovanion
  • 975
  • 7
  • 20

2 Answers2

5

I use the following which is a mashup of the standard doxymacs based one and abo-abo's semantic based one mentioned as an answer already - this only requires semantic and yasnippet. This pre-populates some more of the yasnippet placeholders with relevant info as well compared to abo-abo 's version too.


# -*- mode: snippet -*-
# name: dox
# key: dox
# type: command
# --
(unless (and (fboundp 'semantic-current-tag)
             semantic-mode)
  (error "Semantic required to use dox snippet"))
(let ((tag (senator-next-tag)))
  (while (or (null tag)
             (not (semantic-tag-of-class-p tag 'function)))
    (setq tag (senator-next-tag)))
  (let* ((name (semantic-tag-name tag))
         (attrs (semantic-tag-attributes tag))
         (args (plist-get attrs :arguments))
         (return-name (plist-get attrs :type))
         (idx 1))
    (if (listp return-name)
      (setq return-name (car return-name)))
    (yas/expand-snippet
     (format
      "/**
* @brief ${1:%s}
*
%s
%s*/
"
      name
      (mapconcat
       (lambda (x)
         (format "* @param %s ${%d:Description of %s}"
                 (car x) (incf idx) (car x)))
       args
       "\n")
      (if (and return-name (not (string-equal "void" return-name)))
          (format " * @return ${%d:%s}\n" (incf idx) return-name)
        "")))))

alexmurray
  • 281
  • 1
  • 5
  • This solution absolutely works, but having to wait for semantic mode to chug through all the required code is slightly cumbersome. I've also had emacs getting stuck in endless loops if I write dox before a variable instead. But one can't have everything in this world :D – Rovanion Feb 19 '15 at 10:43
  • this should be voted higher than the above, as it is richer than moo-doxygen – Alejandro Erickson Mar 16 '16 at 17:41
  • what command do i use to execute this function and generate documentation? – Matthaeus Gaius Caesar Mar 07 '23 at 22:13
3

Just added this feature to function-args.

Here's the code, if you're interested. It's using CEDET:

(defun moo-doxygen ()
  "Generate a doxygen yasnippet and expand it with `aya-expand'.
The point should be on the top-level function name."
  (interactive)
  (move-beginning-of-line nil)
  (let ((tag (semantic-current-tag)))
    (unless (semantic-tag-of-class-p tag 'function)
      (error "Expected function, got %S" tag))
    (let* ((name (semantic-tag-name tag))
           (attrs (semantic-tag-attributes tag))
           (args (plist-get attrs :arguments))
           (ord 1))
      (setq aya-current
            (format
             "/**
* $1
*
%s
* @return $%d
*/
"
             (mapconcat
              (lambda (x)
                (format "* @param %s $%d"
                        (car x) (incf ord)))
              args
              "\n")
             (incf ord)))
      (aya-expand))))

You also need auto-yasnippet. Both packages are available in MELPA.

abo-abo
  • 13,943
  • 1
  • 29
  • 43