Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically insert prototype functions from .h with Emacs

Tags:

c++

emacs

How do I configure emacs to automatically insert prototype functions from .h when opening the corresponding .cc file?.

like image 298
Mark Avatar asked Jul 31 '11 22:07

Mark


3 Answers

I have something like this that I used for doing this when I was doing more C++ coding, using the member-functions package:

(require 'member-function)

;;expand member functions automatically when entering a cpp file
(defun c-file-enter ()
  "Expands all member functions in the corresponding .h file"
  (let* ((c-file (buffer-file-name (current-buffer)))
         (h-file-list (list (concat (substring c-file 0 -3 ) "h")
                            (concat (substring c-file 0 -3 ) "hpp")
                            (concat (substring c-file 0 -1 ) "h")
                            (concat (substring c-file 0 -1 ) "hpp"))))
    (if (or (equal (substring c-file -2 ) ".c")
            (equal (substring c-file -4 ) ".cpp"))
        (mapcar (lambda (h-file)
                  (if (file-exists-p h-file)
                      (expand-member-functions h-file c-file)))
                h-file-list))))

(add-hook 'c++-mode-hook c-file-enter)

You can find member-functions.el at: http://www.emacswiki.org/emacs/member-functions.el

like image 160
Nathaniel Flath Avatar answered Nov 15 '22 17:11

Nathaniel Flath


I wrote this hack a while back ... it's not great, but could be a starting point. To use it, start in the .cc file where you want the function implementation inserted, switch to the .h file and go to the function definition, then M-x my-c-make-function-from-prototype (I have it bound to a key of course).

(require 'ffap)
(defun my-c-make-function-from-prototype ()
  "Turn a function prototype into a skeleton implementation."
  (interactive)
  (let (ret-val fcn-name args const namespaces start-of-fcn)
    (save-excursion
      (end-of-line)
      (c-beginning-of-statement 1)
      (beginning-of-line)
      (when (re-search-forward
             "\\s-*\\(.*\\)\\s-+\\([-a-zA-Z0-9_!=<>~]+\\)\\s-*[(]" nil t)
        (setq ret-val (match-string 1))
        (setq ret-val (replace-regexp-in-string "\\(virtual\\|static\\)\\s-*" "" ret-val))
        (setq fcn-name (match-string 2))
        (when (re-search-forward "\\([^)]*\\)[)]" nil t)
          (setq args (match-string 1))
          (setq args (replace-regexp-in-string "\\s-*=.+?," "," args))
          (setq args (replace-regexp-in-string "\\s-*=.+?)" ")" args))
          (setq args (replace-regexp-in-string "\\s-*=.+?$" "" args))
          (if (looking-at "\\s-*const")
              (setq const " const")
            (setq const ""))
          (condition-case nil
              (while 't
                (backward-up-list 1)
                (when (re-search-backward
                     "\\(class\\|namespace\\|struct\\)\\s-+\\([a-zA-Z0-9_]+\\)" nil t)
                  (setq namespaces (concat (match-string 2) "::" namespaces))))
            (error nil)))))
    ;; Switch to other file and insert implementation
    (ff-get-other-file)
    (setq start-of-fcn (point))
    (insert (concat ret-val (unless (string= ret-val "") "\n") namespaces fcn-name "(" args ")" const))
    (insert "\n{\n/** @todo Fill in this function. */\n}\n")
    (unless (eobp)
      (insert "\n"))
    (indent-region start-of-fcn (point) nil)
    (goto-char start-of-fcn)
    (when (fboundp 'doxymacs-insert-function-comment)
      (doxymacs-insert-function-comment))))
like image 20
scottfrazer Avatar answered Nov 15 '22 15:11

scottfrazer


I think, that you can combine autoinsert package with CEDET's Senator "Copy tag", but this will require some elisp programming to open file, force parsing of it, and then iterating over function tags...

Although, if you want to copy entire .h, it will easier, although also will involve elisp - you need to insert empty file via auto-insert function, and then copy .h file content using action function that is second element in auto-insert-alist variable. Function will look something like:

 (defun my-auto-insert-h-content ()
   (when buffer-file-name
     (let ((h-filename (concat (file-name-sans-extension buffer-file-name) ".h")))
       (when (file-exists-p h-filename)
        (goto-char (point-min))
        (insert-file-contents h-filename)))))
like image 45
Alex Ott Avatar answered Nov 15 '22 16:11

Alex Ott