Sorry for the (slightly) off-topic question, but it *does* relate to
being able to use emacs for editing Postgres source files:

I'm trying to use emacs for more editing than I have previously (which
was restricted to Makefiles, lisp, and sgml). And I've got at least
two projects which have differing formatting requirements which also
differ from the emacs defaults.

I'm running into trouble trying to get the tab vs space stuff right.
For Postgres, I want to set the tabbing to 4 columns, and to preserve
tabs in the input and output. I think I can do that, with

  (setq tab-width 4)
  (setq standard-indent 4)

though I'm not sure that standard-indent needs to be adjusted at all.

For my other project, I need 2-column indents always space filled, so
no tabs allowed. It happens to be C++, so I can differentiate between
the C code for Postgres.

Anyway, the first complication was working through the fact that emacs
(20.4, if it matters) claims to have loaded "cc-mode" on startup, when
in fact the major mode is actually called "c++-mode" internally. So I
had a devil of a time setting the hooks.

But I'm also having trouble getting things to space-fill when
indenting. I've tried

  (setq c++-mode-hook 'rtc-cc-mode)

  (defun rtc-cc-mode ()
    (setq tab-width 2)
    (setq standard-indent 2)
    (setq indent-tab-mode nil))

which gave me two-column tabs, but I had hoped that nil-ing
indent-tab-mode would space fill. untabify gets rid of the tabs in a
selected region, but the tabs come back if I hit the tab key. I've
tried nil-ing the other values and setting them to zero, but that
seems to revert the behavior to 8 column tabs.

My emacs book got me this far, but the behavior seems to be a bit at
odds with their description and they don't give a specific example
covering this. Any hints would be *greatly* appreciated.

TIA

                    - Thomas

-- 
Thomas Lockhart				lockhart@alumni.caltech.edu
South Pasadena, California

Fri, 03 Dec 1999 16:54:21 +0000
Thomas Lockhart <lockhart@alumni.caltech.edu>
emacs question
Thomas Lockhart <lockhart@alumni.caltech.edu> writes:
> I'm running into trouble trying to get the tab vs space stuff right.
> For Postgres, I want to set the tabbing to 4 columns, and to preserve
> tabs in the input and output. I think I can do that, with
>   (setq tab-width 4)
>   (setq standard-indent 4)
> though I'm not sure that standard-indent needs to be adjusted at all.

> For my other project, I need 2-column indents always space filled, so
> no tabs allowed. It happens to be C++, so I can differentiate between
> the C code for Postgres.

I am not sure whether you have the correct mental model for this, so
here it is: there are two different things going on here, the "physical"
width of tab stops and the "logical" notion of syntax-driven
indentation.  A TAB character stored in a file is displayed as "indent
to the next tab stop", where tab stops are every tab-width columns, 8 by
default.  (I think you can also choose to set up a user-defined list of
tab stop locations, but I've never done that.)  The tab stops have
*nothing* to do with logical indentation of source code --- that's
driven by separate logic that says "indent this many columns relative to
the previous line when you see this kind of syntactic context".  After
the logical-indent code has decided what column it thinks the line
should start at, it then constructs a whitespace prefix of the right
length, which normally will use the right number of tabs and spaces
based on the current "physical" tab stop settings.  When you press TAB
in c++-mode, that doesn't mean "insert one tab character", it means
"reindent the current line by recomputing the appropriate leading
whitespace".  It could insert or delete any combination of tabs and
spaces.  (If you really want to insert one tab character, you use the
usual escape for inserting control codes: control-Q TAB.)

(If you already had your head screwed on straight, sorry for the
digression.)

> But I'm also having trouble getting things to space-fill when
> indenting. I've tried

>   (setq c++-mode-hook 'rtc-cc-mode)

>   (defun rtc-cc-mode ()
>     (setq tab-width 2)
>     (setq standard-indent 2)
>     (setq indent-tab-mode nil))

I doubt that you want to be messing with the default tab-stop-distance
setting here.  And you shouldn't need to mess with standard-indent
either; I have no idea what that controls, but it's not the basis for
indenting in C or C++ mode AFAIK.  The logical indent per syntactic
level in these modes is set by c-basic-offset, which may already be 2
depending on which c-style value you are using.  Finally, as far as
suppressing use of tabs to do logical indentation, you've almost got it
right, but the variable is named "indent-tabs-mode".

Also, if you want to have different conventions for different projects,
setting a c++-mode-hook is probably not the way to go; that will get run
*any* time you visit a c++ file.  I'd suggest a trick that someone
(Peter E. I think) recently pointed out to me: you can pattern-match on
the location of a source file in an auto-mode-alist pattern.  So I've
now got this in my .emacs:

; Cmd to set tab stops &etc for working with PostgreSQL code
(defun pgsql-c-mode ()
  "Set PostgreSQL C indenting conventions in current buffer."
  (interactive)
  (c-mode)			; select major mode to customize
  (setq tab-width 4)		; some people have weird ideas about tabs
  (c-set-style "bsd")		; sets c-basic-offset to 4, plus other stuff
  (c-set-offset 'case-label '+)	; tweak case indent to match PG custom
)

; Invoke pgsql-c-mode automatically when loading appropriate files
(setq auto-mode-alist
      (cons '("\\`/users/postgres/.*\\.[ch]\\'" . pgsql-c-mode)
	    (cons '("\\`/users/tgl/pgsql/.*\\.[ch]\\'" . pgsql-c-mode)
		  auto-mode-alist)))

which means that I get Postgres-customized C mode whenever I visit a
.c or .h file under /users/postgres/ or /users/tgl/pgsql/ (customize
paths to taste of course).

You can use the above defun as-is for Postgres code, and for your other
project you probably want a mode-set command like

(defun foobar-cc-mode ()
  "Set so-and-so's C++ indenting conventions in current buffer."
  (interactive)
  (c++-mode)				; select major mode to customize
  (setq c-basic-offset 2)
  (setq indent-tabs-mode nil))

(You might also want to call c-set-style if the other project doesn't
use GNU-flavor brace layout and so forth --- and you can get really down
and dirty if you need to, by tweaking offsets for individual syntax
elements.  But that's a last resort if you have to adhere to an
unconventional set of layout guidelines.  c-set-style can get you pretty
close to all the popular formats I've heard of.)

This is already OK to invoke by hand, and then you can add some
auto-mode-alist entries to invoke it automatically when you visit
files with the right path prefix and suffix.

> My emacs book got me this far, but the behavior seems to be a bit at
> odds with their description and they don't give a specific example
> covering this. Any hints would be *greatly* appreciated.

The online manual (see control-H I) is generally more up-to-date about
how your particular version works than any book is likely to be.  I'm
using version 19, so I might be a little off about how version 20 works,
but I hadn't heard that they reworked the indent logic in any major way.

It'd be well worth your while to read the manual's section about
"Indentation for Programs"... but in my copy, the last part about
customizing indent tells you about "styles" last, where it probably
should tell you that first instead of presenting the low-level
adjustments first...

Good luck!

			regards, tom lane

Fri, 03 Dec 1999 13:04:03 -0500
Tom Lane <tgl@sss.pgh.pa.us>
Re: emacs question 
<snip helpful intro which I'd like to think I already knew, at least
mostly ;) >

> >     (setq indent-tab-mode nil))
> ... Finally, as far as
> suppressing use of tabs to do logical indentation, you've almost got 
> it right, but the variable is named "indent-tabs-mode".

sheesh, that's it! I was going around in lots of tiny little
circles... :(

> Also, if you want to have different conventions for different 
> projects, setting a c++-mode-hook is probably not the way to go; that 
> will get run *any* time you visit a c++ file.  I'd suggest a trick 
> that someone (Peter E. I think) recently pointed out to me: you can 
> pattern-match on the location of a source file in an auto-mode-alist 
> pattern.  So I've now got this in my .emacs:

Great. I had just been thinking about this, and now I don't have to
figure it out :))

Thanks.

                      - Thomas

-- 
Thomas Lockhart				lockhart@alumni.caltech.edu
South Pasadena, California

Fri, 03 Dec 1999 20:15:10 +0000
Thomas Lockhart <lockhart@alumni.caltech.edu>
Re: emacs question