Is there a way to automatically provide a documentation template for a C function in emacs? For example, let's say I have this function:
const bool are_equal_int_float(const int a, const float b)
{
bool result = false;
// Do work
return result;
}
I want to put the cursor somewhere inside the function and run a command that will parse the declaration and use it to create an explanation above the function. I would end up with something like this (it doesn't have to be the same format):
/* are_equal_int_float
*
* explanation:
*
* params
* a:
* b:
*
* returns:
*/
const bool are_equal_int_float(const int a, const float b)
{
bool result = false;
// Do work
return result;
}
I just wrote an emacs-lisp function called jd-document-c-function-in-emacs
.
Once the emacs-lisp function is evaluated, just put the cursor anywhere inside the C function and type:
M-x
jd-document-c-function-in-emacs
RET
Note that my function works only in a buffer opened with some C-mode
, since, in fundamental
mode, for example, the function beginning-of-defun
goes to the opening curve brace instead of the "real" beginning of the C function.
(defun jd-document-c-function-in-emacs ()
(interactive)
(save-excursion
(save-restriction
(unless (beginning-of-defun)
(error "Could not find %s" 'beginning-of-defun))
;; Narrow to <beginning of fun> <end of arg list>
(narrow-to-region (point) (progn (forward-list) (point)))
(let* ((bod (point-min))
(eolarg (point-max))
(bolarg (progn (goto-char (point-max)) (backward-list) (point)))
(bofname (progn (backward-sexp) (point)))
(eofname (progn (forward-sexp) (point)))
(fname (buffer-substring bofname eofname))
(eoftype (progn
(goto-char bofname)
(backward-word)
(forward-word)
(min (point) bofname)))
(ftype (buffer-substring bod eoftype))
(arg-re (concat "[[:space:]]*"
"\\([^,)]*\\)"
"[[:space:]]+"
"\\([^[:space:]]+\\)"
"[,)]"))
(largt (list))
(largn (list))
(dformat (concat "/* %s\n" " *\n" " * explanation:\n" " *\n"
" * params\n"))
(aformat (concat " * %s:" " (%s)" "\n"))
(rformat (concat " *\n" " * returns:" " (%s)" "\n" " */\n"))
)
(goto-char bolarg)
(forward-char) ; skip lpar
(while (re-search-forward arg-re eolarg 'noerror)
(let ((argt (buffer-substring (match-beginning 1) (match-end 1)))
(argn (buffer-substring (match-beginning 2) (match-end 2))))
(setq largt (nconc largt (list argt)))
(setq largn (nconc largn (list argn)))))
(goto-char bod)
(insert (format dformat fname))
(cl-mapc (lambda (argn argt) (insert (format aformat argn argt)))
largn largt)
(insert (format rformat (if (string-blank-p ftype) "void" ftype)))))))
HTH