From: kevin@edscom.demon.co.uk (Kevin Broadey)
Subject: Re: C autoindent and macros
X-Disclaimer: These opinions are mine: others available on request.
Reply-To: Kevin Broadey <kbroadey@edscom.demon.co.uk>
Organization: EDS-Scicon, Milton Keynes, UK
Date: Mon, 14 Sep 1992 16:40:32 GMT

>>>>> In article "C autoindent and macros", "Fred" ==
>>>>> proctor@cme.nist.gov (Fred Proctor) writes:

Fred> I use a couple of the emacs variables for auto indentation of C
Fred> code in my emacs buffers, but these don't apply for code in a
Fred> macro which spans several lines that end in the backslash
Fred> continuation character.  Does anyone know how to fix this so
Fred> macros whose intermediate lines are terminated with the backslash
Fred> are formatted as if they were straight C code?

The answer an hour ago was that c-mode can't be configured that way, so
I wrote you a message detailing the way you could get round it by
narrowing to the macro definition, deleting the backslashes, doing the
edit (on code which now looks like a statement or function definition),
replacing the backslashes and widening back to the full buffer.

Then I though "it would be useful to have a command to do the
nitty-gritty - it should be fairly straightforward".

Here is the product of my efforts.

Thanks for the problem!

Enjoy.

--Kevin

-- snip -- snip -- snip -- snip -- snip -- snip -- snip -- snip -- snip --

;; c-edit-macro.el
;;
;; Written by Kevin Broadey <kbroadey@edscom.demon.co.uk>
;; 14-Sep-92
;;
;; Usual GNU conditions - Copyleft and no warranty.

(provide 'c-edit-marco)

(defvar c-macro-backslash-column 72
  "*Column for c-edit-macro to put \"\\\" at in multi-line macros.

    0 puts one space between code and backslash.
    NIL puts backslash immediately after code.")

(defun c-edit-macro ()
  (interactive)
  (let (define-start name-start end)

    ;; Find the first line of the macro.
    (save-excursion
      (beginning-of-line)
      (while (and (not (looking-at "#define[ \t]+"))
		  (not (bobp)))
	(backward-char 1)		; end of preceding line
	(if (/= (preceding-char) ?\\ )
	    (error "Not in a macro definition."))
	(beginning-of-line))
      (if (not (match-beginning 0))
	  (error "Not in a macro definition."))

      (setq define-start (match-beginning 0))
      (setq name-start (match-end 0)))

    ;; Find the last line of the macro.
    (save-excursion
      (end-of-line 1)
      (while (and (= (preceding-char) ?\\ )
		  (not (eobp)))
	(end-of-line 2))		; go to end of next line
      (setq end (point)))

    ;; Restrict buffer to macro definition, and set inner restriction to mask
    ;; out "#define" so code looks like a function definition.
    (save-restriction
      (narrow-to-region define-start end)
      (save-restriction
	(narrow-to-region name-start end)

	;;  Get rid of trailing backslashes.
	(save-excursion
	  (goto-char (point-min))
	  (replace-regexp "[ \t]*\\\\\n" "\n"))

	;; Enter recursive edit.
	(message "Type M-C-c (exit-recursive-edit) to finish.")
	(message (substitute-command-keys
		  "Type \\[exit-recursive-edit] to finish."))
	(recursive-edit)

	;; Recursive edit over - put back trailing backslashes.

	)				; end of inner restriction - "#define"
					; is now visible so `indent-to' will
					; get the target column right.
      (save-excursion
	(goto-char (point-min))
	(end-of-line 1)
	(while (not (eobp))
	  (let ((eol (point)))
	    (skip-chars-backward " \t")
	    (or (eolp)
		(delete-region (point) eol))) ; delete trailing whitespace
	  (if c-macro-backslash-column
	      (indent-to c-macro-backslash-column (if (bolp) 0 1)))
	  (insert "\\")
	  (end-of-line 2))		; end of next line
	;; Delete trailing whitespace on last line.
	(let ((eol (point)))
	  (skip-chars-backward " \t")
	  (or (eolp)
	      (delete-region (point) eol))) ; delete trailing whitespace
	))))

-- snip -- snip -- snip -- snip -- snip -- snip -- snip -- snip -- snip --
Newsgroups: gnu.emacs.help,comp.mail.sendmail