There are quite a few concepts in Emacs which relate to white space at the beginning of a line. Enough, in fact, to be potentially quite confusing. I'll try to clear up the confusion in this little document. The following concepts come into play:
Contrary to popular belief, the TAB key does not insert a tab character in most modes. Instead, it does syntax-driven indentation in most programming language modes. In fundamental mode, it advances to the next tab stop. In text mode, it does relative indentation (relative to the previous line, that is). You can type C-q TAB to insert a tab character.
It is possible to change the way a tab character is displayed. `vi' users do this. For example, they can set the width of a tab character to 4, and this enables them to hit TAB at the beginning of a line to indent the body of a loop, say, by one indentation step (of 4 characters). Normally, the width of tab is eight characters, so a file created by a `vi' user with a tab width of 4 will look different when viewed in a program which uses the default tab width setting.
In order to correctly view files with non-standard tab width
settings, it is possible to set the variable tab-width
, like this:
(setq-default tab-width 4)
If you only want this in a particular mode, add (setq tab-width
4)
to that mode's hook. (See below for an explanation of mode hooks.)
Whether by syntax-driven indentation, or relative indentation (text
mode), or advancing to the next tab stop (fundamental mode), indentation
needs to insert white space. The variable indent-tabs-mode
controls whether or not tab characters are used for inserting the white
space. If this variable is t
, tab characters are used to make
the file as short as possible. For example, if tab-width
is
equal to 4 and white space of 10 characters needs to be inserted at the
beginning of the line, Emacs will insert 2 tab characters (2 times 4
equals 8 spaces), plus two space characters. With tab-width
equal to the default value of 8, Emacs would insert 1 tab plus 2 spaces.
Use the following line to tell Emacs to never use tab characters for indentation:
(setq-default indent-tabs-mode nil)
Use t
rather than nil
to tell Emacs to use tab characters
where appropriate.
If you only want this in a particular mode, add (setq
indent-tabs-mode nil)
to that mode's hook. (See below for an
explanation of mode hooks.)
By the way, actual tab characters are really needed in Makefiles; thus, makefile mode overrides this setting.
The variable tab-stop-list
contains a list of tab stop positions,
and M-i moves to the next tab stop. (In fundamental mode,
TAB also does this.) You can define your own list with a
statement like the following:
(setq tab-stop-list '(4 8 12 16))
Whether or not actual tab characters are inserted is controlled by
the variable indent-tabs-mode
, and the number of tab characters
inserted is controlled by tab-width
(among others).
Obviously, if you set tab-stop-list
to a list containing multiples
of tab-width
, then one M-i will insert one tab character at all
times (if indent-tabs-mode
isn't nil
).
The variable tab-stop-list
controls which spots M-i moves
to, and indent-tabs-mode
controls whether tab characters (plus
maybe a few space characters) are used to move to that spot, and
tab-width
controls how many tab characters are needed.
This means that the current line is indented in a way that is useful for
the syntax of the programming language used. For example, in C-like
languages, the lines between an opening and a closing brace are usually
indented two to four spaces with respect to the braces themselves. In
Pascal, the lines between begin
and end
would be indented
two to four spaces.
Since the syntax driven indentation depends a lot on the syntax of the programming language at hand, the major mode provides the indentation. And customizing each major mode works a little differently, because the programming languages are different.
For C-like languages, there is `CC mode'. It provides major modes for C, C++, Objective C, IDL, and Java. The indentation engine is quite flexible, and the CC mode info file has the whole story on customizing indentation for these major modes. I'll just mention a few things.
CC mode provides for different coding styles. Type M-x c-set-style
RET, then use tab completion to have a look at them, and try them
out. If you find one you like, you can add something like
(c-set-style "gnu")
to your mode hook. These coding styles often
refer to a basic indentation offset, determined by the variable
c-basic-offset
. Add stuff like (setq c-basic-offset 4)
to
the mode hook in question.
If this isn't sufficient, you can go to the line where you don't like
the indentation, and type C-c C-o. Follow the prompts. Hit
TAB to re-indent the current line. Repeat until you like the
result. You can then type C-x ESC ESC and use
M-n and M-p to locate the right `c-set-offset'
statement to add to your hook. Please note that you can enter numbers
for the indentation level, but you can also use +
and -
to
stand for one basic offset to the right or left, respectively, or
++
and --
for twice the basic offset.
I use `CPerl' mode for editing Perl code. It also provides a style
mechanism similar to the one provided by CC mode, but it doesn't provide
an interactive command which allows one to customize indentation, like
C-c C-o in CC mode. Type C-h f cperl-mode RET for a
list of variables affecting indentation. Choose an indentation style
which is closest to what you want, then change the remaining variables
from your mode hook. You can choose an indentation style by adding
something like (cperl-set-style "gnu")
to your mode hook.
CCC Can people provide info for other modes?
This means indent to a spot indicated by the previous non-blank line. Below, the spots relative indentation moves to are indicated with a caret.
This is a line to show relative indentation. ^ ^ ^ ^ ^ ^ ^ ^
I find this useful for text where it can be used to format tables or to
indent itemized lists. When in text mode, the TAB key performs
relative indentation by default. The command name is
indent-relative
.
In the above, I explained the concepts behind the things Emacs is doing, but I suspect you'd like some advice on when to frob which options.
Since `vi' doesn't have syntax driven indentation, its users usually
set the tab width to some value they like, and whenever they want to
indent a line more than the previous one, they hit TAB. Of course,
a file which was edited in this way will look strange when loaded into
Emacs. The variable tab-width
was made for this, just set it to the
tab width your `vi' loving colleagues use, and you can continue to use
syntax driven indentation and your cow-orkers will wonder why you can
edit code so fast@enddots{}
Perhaps you also want to set indent-tabs-mode
to t
(which
is the default) such that Emacs actually uses tabs with the new width.
But then, maybe you want to set it to nil
such that Emacs uses
only spaces and the looks of your code won't depend on the tab width
setting somebody uses.
And you might need to customize your indentation to be similar to the style used by the others, lest you need to do a lot of manual reformatting. A consistent coding style is a good thing.
This section provides background information referred to in the above.
A central concept in Emacs is the major mode. For each kind of text, a major mode provides functions useful in that mode. Most (if not all) major modes provide a so-called hook which allows you to specify Lisp code to be run when that major mode is entered. Most of the time, this feature is used just for setting a few variables.
A mode hook is a variable which contains a list of functions to be executed. Thus, if you want something to happen, you have to write a function first. Writing functions is rather simple, finding a name for the function might be the most difficult part, in fact!
So, let's say you wish to set the variable c-basic-offset
to 3 when
in C++ mode. Additionally, you want to use no tabs for indentation.
Here's a function which does this:
(defun my-c++-indent-setup () (setq c-basic-offset 3) (setq indent-tabs-mode nil))
Pay careful attention to the nesting of the parentheses. The empty
pair of parentheses is always needed, and the parenthesis opened
before the word defun
is closed at the very end of the function.
So, all that's left is to add this function to the mode hook for C++ mode. Easy:
(add-hook 'c++-mode-hook 'my-c++-indent-setup)
You may wish to replace the `my' prefix with something else such that you can be sure not to reuse a function name already defined elsewhere. I use the prefix `kai', for example. This means I've got to be careful when snarfing code from Kai-Uwe Rommel :-)
Go to the first, previous, next, last section, table of contents.