help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: regexp / replacement for variable


From: Floyd Davidson
Subject: Re: regexp / replacement for variable
Date: Sun, 22 Feb 2004 03:14:12 -0900
User-agent: gnus 5.10.6/XEmacs 21.4.15/Linux 2.6.0

Jan Misol <misol@liblss.org> wrote:
>I'm new to elisp but I want my beloved editor
>to generate the standard c-header stuff when creating
>a new .h/.hpp header.
>
>> c-x c-f test.h
>
>should automatically insert:
>
>   #ifndef _TEST_H_
>   #ifndef _TEST_H_
>
>   #endif
>
>depending on the given filename.

We probably want to use more of the filename than just the
base, to allow similar header files in different directories
without name space collisions.

>I put the following to my .emacs file:
>
>   (defun new-c-header ()
>     "Insert c-header skeleton."
>     (interactive "")
>     (progn
>       (setq bname (upcase(buffer-name)))
>       (insert
>        (message "#ifndef %s\n\#define %s\n\n#endif"
>           bname bname))))
>
>Apart from knowing that "message" might not be the right
>choice here, I don't know how to modify the value of bname!?
>"replace-regexp" doesn't seem to be the what I'm looking for.
>
>(and how could the new-c-header() be invoked by creating a
>new .h/.cpp file?)
>
>jan

There are some other considerations too.  It is nice if this is
automatic, but it also must avoid trying to add the #define to
system headers and/or headers from other packages that are just
being looked at.

Below is one way to do that.  It decides that a file is "empty"
if it has fewer than 34 bytes in it, and otherwise will not make
an insertion.  When it does, it will include directories from
the pathname up to a maximum of to 32 characters total (by
default, which can be re-configured on the fly) into the symbol
name used for the #define.

Incidentally, it might be useful to expand on this concept and
make it more general.  Instead of running it from the
c-mode-hook as I've done below, it could be run from the
find-file-hook, and use an alist of regular expressions and
associated boilerplate files.  Similar to the auto-mode-alist,
it would insert user defined boilerplate based on the filename
being edited.  The file to insert could be massaged by a fairly
simple set of macro sustitutions built into the insertion
process to allow using environment variables and Emacs functions
or variables on a per instance basis triggered by macros in the
boilerplate.

Hmmm... sounds like a default "forms" boilerplate; somebody must
have done that already...

;;;
;;;  Insert boilerplate into a new header file
;;;
(defvar fld-header-name-width-max 32)
(defun fld-new-h-header ()
  (interactive)
  (let (
        ;; get file name and extension
        (name (upcase (file-name-sans-extension (buffer-file-name))))
        (extn (upcase (file-name-extension (buffer-file-name)))))

    ;; trim off excessive length
    (when name
      (let ((start 0))
        (while (and (< fld-header-name-width-max (string-width name))
                    (< start (string-width name)))
          (progn
            (when (string= (substring name start (1+ start)) "/")
              (progn
                (setq name (substring name (1+ start) nil))
                (setq start -1)))
            (setq start (1+ start))))))
    ;; to mung, or not to mung...
    (when (or (string= extn "HPP") (string= extn "H"))
      (save-excursion
        (when (< (point-max) 34)
          (progn
            (goto-char (point-min))
            (insert (format "#ifndef _%s.%s_\n#define _%s.%s_\n\n#endif"
                            name extn name extn))))))))

;; add it to c-mode (which assumes the appropriate suffixes are
;; in the auto-mode-alist to enable c-mode for the target files.
(add-hook 'c-mode-hook 'fld-new-h-header)

--
Floyd L. Davidson           <http://web.newsguy.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska)                         floyd@barrow.com


reply via email to

[Prev in Thread] Current Thread [Next in Thread]