Skip to content

Instantly share code, notes, and snippets.

@drshapeless
Created September 27, 2024 15:43
Show Gist options
  • Save drshapeless/e39ca16d583048e826ec4fa0dfc503b3 to your computer and use it in GitHub Desktop.
Save drshapeless/e39ca16d583048e826ec4fa0dfc503b3 to your computer and use it in GitHub Desktop.
Generate c++ class function definition using treesit in Emacs
;; This is a cpp helper function to easily create definition from declaration
(defun drsl/cpp-definition-in-class ()
"Format the current declaration of function into definition and
put it into kill-ring."
(interactive)
(kill-new
(drsl/generate-cpp-class-function-definition-at-point))
(message "definition is put in kill-ring"))
(defun drsl/get-cpp-template-node (class-node)
"Return parent template treesit node.
Return nil if is not in a template."
(treesit-parent-until class-node
(lambda (NODE)
(string-equal (treesit-node-type NODE)
"template_declaration"))))
(defun drsl/get-class-function-node-at-point ()
"Return a treesit node of the current class function."
(treesit-parent-until (treesit-node-at (point))
(lambda (NODE)
(string-equal (treesit-node-type NODE)
"field_declaration"))
t))
(defun drsl/get-cpp-class-node-at-point ()
"Return the current class treesit node."
(treesit-parent-until (treesit-node-at (point))
(lambda (NODE)
(let ((NODE-TYPE (treesit-node-type NODE)))
(or (string-equal NODE-TYPE
"class_specifier")
(string-equal NODE-TYPE
"struct_specifier"))))
t))
(defun drsl/generate-cpp-class-function-definition-at-point ()
"Return the class function definition at point."
(interactive)
(string-replace
";"
" {\n\n}"
(let* ((class-node (drsl/get-cpp-class-node-at-point))
(func-node (drsl/get-class-function-node-at-point))
(template-node (drsl/get-cpp-template-node class-node))
(class-text (treesit-node-text
(treesit-node-child-by-field-name
class-node
"name")
t))
(func-text (treesit-node-text
func-node
t))
(first-space-pos (string-match " "
func-text))
(insert-pos (string-match "[a-z]"
func-text
first-space-pos)) )
(if template-node
(let* ((template-parameter (treesit-node-text
(treesit-node-child-by-field-name
template-node
"parameters")
t))
(template-head (concat "template "
template-parameter
"\n"))
)
(concat template-head
(substring func-text 0 insert-pos)
class-text
(string-replace "typename " "" template-parameter)
"::"
(substring func-text insert-pos))
)
(concat (substring func-text 0 insert-pos)
class-text
"::"
(substring func-text insert-pos))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment