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

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

Re: indentation


From: Gareth Rees
Subject: Re: indentation
Date: 23 Oct 2003 06:19:06 -0700

Yen Tran wrote:
> How do I leave indentation mode unchanged?  For example, if current
> *.c or *.cpp file is using 5 spaces as indentation, then use 5 spaces;
> if it's using 4-space tab, then use tab.
> 
> By default, everything I edit with Emacs adds tab to file.

Emacs indentation behaviour in C mode is under the control of these
variables:

* 'indent-tabs-mode'
   Indentation can insert tabs if this is non-nil.
* 'tab-width'
  Distance between tab stops (for display of tab characters), in columns.
* 'c-basic-offset'
  Amount of basic offset used by + and - symbols in 'c-offsets-alist'.

The best thing to do is to agree with all your colleagues to use spaces
for indentation (hence indent-tabs-mode should be nil) and how many of
them.  Then you and they can set editor settings accordingly.

The next best thing to do is to specify behaviour for different files by
putting a local variables section into the file (see the Info node
(emacs)File Variables).  For example, a file using indentation of 5
spaces should have the following somewhere near the end:

    /* Local Variables: */
    /* indent-tabs-mode: nil */
    /* c-basic-offset: 5 */
    /* End: */

while a file using tab characters for indent which you want to display
with tab stops every 4 characters should have the following:

    /* Local Variables: */
    /* indent-tabs-mode: t */
    /* tab-width: 4 */
    /* c-basic-offset: 4 */
    /* End: */

If this is no good either, then you could write something that guesses
the settings for the file, and put that in c-mode-hook.  For example,
you might do something like this:

    (defun guess-indent-settings ()
      (save-excursion
        (goto-char (point-min))
        ;; Don't guess if local variables already set.
        (when (and (not (search-forward "Local Variables:" nil t))
                   (re-search-forward "\\([\t ]*\\).*{\n\\1\\(\t\\| +\\)"
                                      nil t))
          (make-local-variable 'c-basic-offset)
          (if (string= (match-string 2) "\t")
              (setq indent-tabs-mode t
                    tab-width 4         ; See note below
                    c-basic-offset 4)   ; Ditto
            (setq indent-tabs-mode nil
                  c-basic-offset (length (match-string 2)))))))

    (add-hook 'c-mode-hook 'guess-indent-settings)

Note that when code uses tab characters for indenting, there's no way to
automatically guess by reading the file how many columns are needed per
tab stop.  A good reason not to use that indentation style!

As a last resort, I suppose you could look at the filename and apply
some rules based on what you know about the different projects you work
on, perhaps like this:

    (setq indent-tabs-mode nil
          c-basic-offset
          (let ((f (buffer-file-name)))
            (cond ((string-match "/projects/foo/" f) 5)
                  ((string-match "/projects/bar/" f) 8)
                  (t 4))))

-- 
Gareth Rees   http://www.garethrees.org/


reply via email to

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