[net.emacs] gnu emacs C mode frobbozery

mly@mit-prep (05/28/85)

From: Richard Mlynarik <mly@mit-prep>
   From: sdcarl!rusty@mit-eddie (rusty c. wright)
   Newsgroups: net.emacs
   Date: Sat, 25-May-85 17:06:44 EDT

   I'd like to use emacs' C mode but it seems that i have to go
   to extra trouble to use tabs when they aren't at the beginning
   of a line.  for example i like to code my declarations as

   [...]

   where there is one or more tabs in front of the variables so that
   they all line up.  when i try to type a tab here the cursor just
   stays there.  i finally discovered that i could use ctl-q ctl-i
   but that is unreasonable.
Actually, not all that excessively unreasonable...
I use m-tab (same as in zmacs) for this purpose; it is both faster to
type and surprisingly unobtrusive.

   is there some way i can get what i want? (be able to just use the
   tab key in the middle of lines as well as at the beginning.)

Well, it is usually very difficult to define exactly what it is that
one "wants" -- it seems clear that a program isn't doing it, but it's
very hard to work out what one could change to make things "right."

One solution might be to make tab act as an indenter only when the
cursor is inside whitespace at the beginning of a line; for example

(defun rusty-c-indent-line (&optional whole-exp)
  "Indent current line as C code if at the start of a line
or within whitespace which beings a line.  Argument means shift any
additional lines of grouping rigidly with this line.

If not in start-of-line whitespace, then just insert a tab character."
  (interactive "P")
  (if (save-restriction
	(save-excursion
	  ;; consider only the region from start of line to dot
	  (narrow-to-region (dot) (progn (beginning-of-line 1) (dot)))
	  ;; see if it is a sequence of only spaces and tabs
	  (looking-at "[ \t]*\\'")))
      ;; if in the middle of start-of-line spaces and tabs,
      ;;  do the usual c-indentation thing.
      (c-indent-line whole-exp)
    ;; else insert a tab character.
    (insert "\t")))

; a form for your .emacs file
(setq c-mode-hook '(lambda () (local-set-key "\t" 'rusty-c-indent-line)))

You might also like to hack up the rubout function (which is
backwards-delete-char-untabify by default in c-mode) so that it nukes
tab characters completely when not in beginning-of-line-whitespace,
exploding them into spaces when not.