(defun treesit-docgen--get-function-node (node) "Get the function node the given NODE belongs to. Or nil" (treesit-parent-until node (lambda (n) (or (equal (treesit-node-type n) "function_definition") (and (equal (treesit-node-type n) "declaration")) (equal (treesit-node-type (treesit-node-child-by-field-name n "declarator")) "function_declarator"))) t) ) (defun treesit-docgen--fn-template-node (fn-node) "Get the template node of a function or nil" (let* ((par (treesit-node-parent fn-node)) (par-t (treesit-node-type par))) (when (string= par-t "template_declaration") par) )) (defun treesit-docgen--fn-tpars (fn-node) "Get the template parameters of the function node or nil" (let* ((template (treesit-docgen--fn-template-node fn-node)) (tpars (treesit-node-child-by-field-name template "parameters"))) (when tpars (delq nil (mapcar (lambda (tpar) (when (string= (treesit-node-type tpar) "type_parameter_declaration") (treesit-node-text tpar))) (treesit-node-children tpars)))))) (defun treesit-docgen--fn-type (fn-node) "Get the return type of the function node" (let ((fn-type-node (treesit-node-child-by-field-name fn-node "type"))) (treesit-node-text fn-type-node))) (defun treesit-docgen--fn-pars (fn-node) "Get the parameter names of the function node" (let* ((fn-node-decl (treesit-node-child-by-field-name fn-node "declarator")) (fn-node-pars (treesit-node-child-by-field-name fn-node-decl "parameters")) ) (when fn-node-pars (delq nil (mapcar (lambda (par) (when (string= (treesit-node-type par) "parameter_declaration") (treesit-node-text par))) (treesit-node-children fn-node-pars)))))) (defun treesit-docgen-insert-doc () "Insert a documentation template for the function at point" (interactive) (let* ((node (treesit-node-at (point))) (fn-node (treesit-docgen--get-function-node node))) (when fn-node (let* ((fn-type (treesit-docgen--fn-type fn-node)) (fn-pars (treesit-docgen--fn-pars fn-node)) (fn-tpars (treesit-docgen--fn-tpars fn-node))) (goto-char (treesit-node-start (or (treesit-docgen--fn-template-node fn-node) fn-node))) (insert "///\n") (insert "///@brief\n") (insert "///\n") (when fn-tpars (dolist (tpar fn-tpars) (insert "///@tparam " tpar "\n")) (insert "///\n")) (when fn-pars (dolist (par fn-pars) (insert "///@param " par "\n")) (insert "///\n")) (when fn-type (insert "///@return " fn-type "\n") (insert "///\n") )))))