Automatically insert prototype functions from .h with Emacs
How do I configure emacs to automatically insert prototype functions from .h when opening the corresponding .cc file开发者_如何学C?.
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
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))))
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)))))
精彩评论