IndentationBasics

The <tab> key is usually bound to do some mode-specific indentation. People new to Emacs often feel like they just want <tab> to insert a tab. This is of course possible, but discouraged. Why make Emacs dumber than it is? Emacs can figure out how much indentation you need and do the right thing!

Remember, often the indentation engines of major modes can be customized. Specially modes based on CC Mode are notorious for their support of styles. See IndentingC for examples.

Basic Control

The variable indent-tabs-mode controls whether tabs are used for indentation. It is t (true) by default; to deactivate it, put the following in .emacs.

    (setq-default indent-tabs-mode nil)

The rest of this page will assume tabs are used and discuss the use of the following two variables:

You should ensure these variables have the same value to avoid interoperability problems with other editors (TextMate, for example) that are unable to separate tab width from indentation. The following will merge the indentation offset and tab width variables for Emacs as well:

    (setq tab-width 4) ; or any other preferred value
    (defvaralias 'c-basic-offset 'tab-width)
    (defvaralias 'cperl-indent-level 'tab-width)

With this set-up, all lines but continuation lines become independent of the tab size used by the programmer. To fix continuation lines too, see SmartTabs.


The following two commands will be useful when looking at the examples below:

If you are indenting Perl and the mode is configured to indent by four, and you didn’t change the variables above, then the following example will use no tabs! There are no eight spaces in it to replace with a tab.

    sub SmileyReplace {
      foreach my $regexp (keys %Smilies) {
        if (m/\G($regexp)/cg) {
          return $q->img({-src=>$Smilies{$regexp}, -alt=>$1, -class=>'smiley'});
        }
      }
    }

If indent-tabs-mode is t and tab-width is 4, however, you will see three tabs looking four spaces wide:

    sub SmileyReplace {
      foreach my $regexp (keys %Smilies) {
    ____if (m/\G($regexp)/cg) {
    ____  return $q->img({-src=>$Smilies{$regexp}, -alt=>$1, -class=>'smiley'});
    ____}
      }
    }

If you are collaborating with other people, however, and they use different settings, things will get ugly. The tabs may look twice as wide, since the default is 8:

    sub SmileyReplace {
      foreach my $regexp (keys %Smilies) {
    ________if (m/\G($regexp)/cg) {
    ________  return $q->img({-src=>$Smilies{$regexp}, -alt=>$1, -class=>'smiley'});
    ________}
      }
    }

Thus, you should either not change tab-width, or make sure that it matches whatever the indentation steps of your current major mode are.

If you are a die-hard tab user, try using a tab-width of 2. Here’s how it will look for you:

    sub SmileyReplace {
    __foreach my $regexp (keys %Smilies) {
    ____if (m/\G($regexp)/cg) {
    ______return $q->img({-src=>$Smilies{$regexp}, -alt=>$1, -class=>'smiley'});
    ____}
    __}
    }

And here for the other poor bastards:

    sub SmileyReplace {
    ________foreach my $regexp (keys %Smilies) {
    ________________if (m/\G($regexp)/cg) {
    ________________________return $q->img({-src=>$Smilies{$regexp}, -alt=>$1, -class=>'smiley'});
    ________________}
    ________}
    }

In summary:

Project-specific Indentation Configuration

If your .emacs is set-up to do indentation one way and you are contributing to a project that expects indentation to be done in a different way, then you might want DirectoryVariables. For example, if you usually use spaces ((indent-tabs-mode nil)) to indent, and the project you’re working on uses tabs, then you can add a .dir-locals.el to the root directory of the project to make Emacs treat files in the project specially. Here’s an example .dir-locals.el that uses tabs and highlights leading spaces to keep you honest:

    ;; The 'nil' configuration applies to all modes.
    ((nil . ((indent-tabs-mode . t)
            (tab-width . 2)))
     (haskell-mode . (
            ;; Highlight leading space characters in Haskell files.
            (eval . (highlight-regexp "^ *")))))

Smart Tabs

Is it possible to make Emacs use a smart mix of tabs and spaces?

Yes, it is possible. See SmartTabs.


CategoryIndentation