123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- ;;; jao-skel-cpp.el -*- lexical-binding: t; -*-
- ;; Copyright (C) 2004, 2005, 2008, 2009, 2022 Jose Antonio Ortega Ruiz
- ;; Author: Jose A Ortega Ruiz <jao@gnu.org>
- ;; Keywords: tools
- ;; This file is free software; you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation; either version 3, or (at your option)
- ;; any later version.
- ;; This file is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
- ;; You should have received a copy of the GNU General Public License
- ;; along with GNU Emacs; see the file COPYING. If not, write to
- ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- ;; Boston, MA 02111-1307, USA.
- ;;; Commentary:
- ;; C/C++ skeletons.
- ;;; Code:
- (require 'jao-skel)
- (require 'thingatpt)
- ;;; Variables
- (defvar jao-skel-cpp-root-namespace nil
- "The root C++ namespace")
- (defvar jao-skel-cpp-brief-header-p nil
- "If non-nil, generate brief header comments")
- (defvar jao-skel-cpp-make-guard-function #'jao-skel-cpp-make-guard-name
- "Function generating #include guards")
- (defvar jao-skel-cpp-use-namespaces t
- "Whether to generate namespaces")
- (defvar jao-skel-cpp-single-line-namespaces t
- "Whether to put consecutive namespace decls in a single line")
- (defvar jao-skel-cpp-header-extension "hpp")
- ;;; Auxiliar functions
- (defun jao-skel-cpp--find-other (ext)
- (file-name-nondirectory
- (or (ff-other-file-name)
- (concat (file-name-sans-extension (buffer-name)) "." ext))))
- (defun jao-skel-cpp-make-guard-name (ns)
- "Create a standard include guard name"
- (upcase (mapconcat #'identity
- `(,@ns ,(jao-skel-basename) ,(jao-skel-extension)
- ,(user-login-name)
- ,(format-time-string "%y%m%d%H%M"))
- "_")))
- ;; namespaces
- (defsubst jao-skel-cpp--read-ns (curr)
- (read-string (format "Add namespace (current: %s): " (or curr "[none]"))))
- (defsubst jao-skel-cpp--ns2str (ns) (mapconcat 'identity ns "::"))
- (defun jao-skel-cpp--get-ns-list (&optional acc)
- (do* ((result acc (cons next result))
- (next (jao-skel-cpp--read-ns (jao-skel-cpp--ns2str acc))
- (jao-skel-cpp--read-ns (jao-skel-cpp--ns2str (reverse result)))))
- ((string= next "") (reverse result))))
- (defun jao-skel-cpp--insert-open-ns-list (ns)
- (dolist (n ns)
- (insert (format "namespace %s {%s"
- n
- (if jao-skel-cpp-single-line-namespaces " " "\n")))
- (indent-according-to-mode))
- (when jao-skel-cpp-single-line-namespaces
- (newline)
- (indent-according-to-mode)))
- (defun jao-skel-cpp--insert-close-ns-list (ns)
- (if jao-skel-cpp-single-line-namespaces
- (insert (format "%s // namespace %s\n"
- (make-string (length ns) ?})
- (jao-skel-cpp--ns2str ns)))
- (dolist (n (reverse ns))
- (insert (format "} // namespace %s\n" n)))))
- (defun jao-skel-cpp--copy-ns-lines ()
- (let ((lines))
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward "namespace\\s-\\w+\\s-{\\|}+\\s-//\\s-namespace"
- nil t)
- (push (thing-at-point 'line) lines)
- (next-line)))
- lines))
- (defun jao-skel-cpp--copy-namespace ()
- (let* ((name (ff-other-file-name))
- (buff (and name (find-file-noselect name)))
- (nlines))
- (when buff
- (let ((lines (save-current-buffer
- (set-buffer buff)
- (jao-skel-cpp--copy-ns-lines))))
- (dolist (line lines)
- (push line nlines)
- (when (string-match "}" line)
- (push "\n\n\n\n" nlines)))))
- (mapconcat #'identity nlines "\n")))
- (defsubst jao-skel-cpp--get-new-namespace ()
- (when jao-skel-cpp-use-namespaces
- (jao-skel-cpp--get-ns-list
- (and jao-skel-cpp-root-namespace (list jao-skel-cpp-root-namespace)))))
- ;; skeletons
- (define-skeleton jao-skel-cpp-header-long
- "Initial file header blurb"
- "Brief file description: "
- "/**"
- > \n
- "* @file " (file-name-nondirectory (buffer-file-name))
- > \n
- "* @brief " str
- > \n
- "* @author " (user-full-name) " <"user-mail-address">"
- > \n
- "* @date " (format-time-string "%a %b %d, %Y %H:%M")
- > \n
- "*"
- > \n
- (jao-skel-copyright-line "* " "")
- "*"
- > ?\n
- (jao-skel-insert-license)
- > \n \n _)
- (define-skeleton jao-skel-cpp-header-brief
- "Brief initial header blurb"
- nil
- (jao-skel-copyright-line "/* " " */")
- \n)
- (define-skeleton jao-skel-cpp-header-comment
- "Insert a standard comment block"
- nil
- '(if jao-skel-cpp-brief-header-p
- (jao-skel-cpp-header-brief)
- (jao-skel-cpp-header-long)))
- ;; source C/C++ file ------------------------------------------------------
- (define-skeleton jao-skel-cpp-source-header
- "Insert a standard C++ source header"
- nil
- '(jao-skel-cpp-header-comment)
- ? \n
- "#include \"" (jao-skel-cpp--find-other jao-skel-cpp-header-extension) "\""
- > \n \n _
- (jao-skel-cpp--copy-namespace)
- \n)
- (define-skeleton jao-skel-c-source-header
- "Insert a standard C source header"
- nil
- '(jao-skel-cpp-header-comment)
- "#include \"" (jao-skel-cpp--find-other "h") "\""
- > _ \n \n \n \n
- > \n)
- ;; header C/C++ files ------------------------------------------------------
- ;; header guard
- ;; class definition
- (define-skeleton jao-skel-cpp-class-def
- "Insert a class definition"
- nil
- '(setq v1 (jao-skel-basename))
- > \n
- "/**"
- > \n
- "*"
- > \n
- "*"
- > \n
- "*/"
- > \n
- "class " v1
- > \n
- "{"
- > \n
- "public:"
- > \n
- "~" v1 "();"
- > \n
- v1 "();"
- > \n
- v1 "(const " v1 "& other);"
- > \n \n
- "private:"
- > \n
- "};"
- > \n)
- (define-skeleton jao-skel-cpp-header
- "Insert a standard C++ header (hpp files)"
- nil
- '(setq v1 (jao-skel-cpp--get-new-namespace))
- '(setq v2 (funcall jao-skel-cpp-make-guard-function v1))
- '(jao-skel-cpp-header-comment)
- > \n
- "#ifndef " v2
- > \n
- "#define " v2
- > \n \n
- '(when v1 (jao-skel-cpp--insert-open-ns-list v1))
- _ '(jao-skel-cpp-class-def)
- > \n \n
- '(when v1 (jao-skel-cpp--insert-close-ns-list v1))
- > \n \n
- "#endif // " v2
- > \n)
- (define-skeleton jao-skel-c-header
- "Insert a standard C header (.h files)"
- nil
- '(jao-skel-cpp-header-comment)
- > \n
- '(setq v1 (funcall jao-skel-cpp-make-guard-function nil))
- "#ifndef " v1
- > \n
- "#define " v1
- > _ \n \n \n \n
- "#endif /* " v1 " */"
- > \n > \n)
- (jao-skel-install*
- '(("\\.cpp$" jao-skel-cpp-source-header)
- ("\\.hpp$" jao-skel-cpp-header)
- ("\\.c$" jao-skel-c-source-header)
- ("\\.h$" jao-skel-c-header)))
- (provide 'jao-skel-cpp)
- ;;; jao-skel-cpp.el ends here
|