使用Emacs自动从.h插入原型函数

时间:2011-07-31 22:04:12

标签: c++ emacs

如何配置emacs以在打开相应的.cc文件时自动从.h插入原型函数?

3 个答案:

答案 0 :(得分:4)

我曾经写过这个黑客...它不是很好,但可能是一个起点。要使用它,请从要插入函数实现的.cc文件开始,切换到.h文件并转到函数定义,然后M-x my-c-make-function-from-prototype(我将它绑定到关键当然)。

(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))))

答案 1 :(得分:3)

当我使用member-functions包进行更多C ++编码时,我有这样的东西,我用它来做这个:

(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)

您可以在http://www.emacswiki.org/emacs/member-functions.el

找到member-functions.el

答案 2 :(得分:1)

我认为,你可以将autoinsert包与CEDET的参议员“复制标签”结合起来,但这需要一些elisp编程来打开文件,强制解析它,然后迭代函数 tags ...

虽然,如果你想复制整个.h,它会更容易,虽然也会涉及elisp - 你需要通过auto-insert函数插入空文件,然后使用动作函数复制.h文件内容auto-insert-alist变量中的第二个元素。功能看起来像:

 (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)))))