Home page of Eric Pement

Home > emacs_tabs.htm

 

Understanding GNU Emacs and Tabs

By Eric Pement
Last updated: June 24, 2018

I love Emacs, but getting my head around how it handled TABs and how to make it do what I wanted it to do, was a major source of frustration. I spent several hours trying to figure it out, reading, searching and even grepping info pages. This summary is intended to be understandable by novices to Emacs. If you find mistakes or things I left out, or if it helps you, write me and let me know. This document is always subject to change, so please let me know if you find sections that are inaccurate or incomplete. My most recent change to this file was to update the URL to whitespace-mode.

To truly understand GNU Emacs and TAB behavior, you must bear three things in mind at once. I've written them as questions to ask yourself, but you should also think of them as options that you have the power to re-define. The possible options below are in square boxes.

  1. How many things should be inserted when I press the TAB key?
  2. What should be inserted when I press the TAB key?
  3. How wide do I want TAB spacing to display?

The following section contains the longer, detailed explanations of how GNU Emacs handles this or that aspects of TAB settings. Its sections are linked to the questions above.

Use file variables to override defaults

Although Emacs normally looks at the filetype or file extension (such as *.txt, *.php, *.pl, *.html) to determine what editing mode and variable settings to use when editing a file, you can override this for individual files. If you embed a string of special commands at either the beginning or the end of a file, Emacs will automatically change certain settings such as tab-width, using tabs or spaces, margins, or even editing mode each time it opens that file. For details, see the section on setting file variables.

Convert Tabs to Spaces, and vice-versa

Emacs is also able to change tabs to spaces or to change spaces to tabs in a document or in part of a document. This is useful if you need to modify things wholesale.


How many things should be inserted by the TAB key?

Insert one thing only

Nobody wants to insert just one space when they press a TAB key. If they wanted to insert just one space, they'd press the spacebar. Here's how to insert just one TAB when you press the TAB key (because quite often, Emacs will insert several TABs or combinations of TABs and spaces):

Just this once time, insert just one TAB:

Ctrl-q <TAB>

You can do this anytime while typing, and it doesn't change modes or reset anything. Ctrl-q followed by any (nearly) any other character on the keyboard inserts that literal character into the file. Associate Ctrl-q with the word "quote" to memorize it. But pressing three keys (Ctrl, Q, TAB) to get just one TAB character is clumsy if you need to do it more than a few times. You may want to change this behavior for the rest of the session.

For this session, force just one TAB:

M-x local-set-key<RET> <TAB> self-insert-command

M-x means the Meta-character followed by x. This can be be ESC followed by x, or Ctrl-[ followed by x. Under Microsoft Windows, M-x is equal to ALT-x. The effect of this is to redefine the behavior of the TAB key for that particular buffer, during this session only. If you want to redefine the behavior for all buffers for this session only, do:

M-x global-set-key<RET> <TAB> self-insert-command

Permanently, force TAB to insert just one TAB:

(global-set-key (kbd "TAB") 'self-insert-command);           # in every mode
OR
(define-key text-mode-map (kbd "TAB") 'self-insert-command); # only in text-mode

Edit your .emacs startup file (I assume you know where to find it) and insert only one of the lines on the previous paragraph. Of course, "permanently" means only so long as you have your .emacs file set this way. The global-set-key line will affect every editing mode; the define-key line shows how to change one mode at a time. It doesn't have to be text-mode necessarily; you should be able to use multiple lines to redefine several editing modes.

Either one or many things

The default (normal) behavior of Emacs is to insert one or more TABs or spaces when the TAB key is pressed, depending on (a) which editing mode is active, (b) what the character position is on the line, and in particular, (c) what variables have been set. Mostly, the TAB key is bound to indent-relative or indent-relative-maybe, which means that Emacs looks up to the previous printed line, splits it into words, and each press of the TAB key will move the cursor (the "point") to the next nonblank position on the line. For example:

    A Blue    Cow Doesn't   Exist, Fred.
    Greg_

If the cursor is currently located directly after the word "Greg", then pressing TAB would move it so that it lines up below the "C" in "Cow". Pressing it once more would move it to line up below the "D", and then below the "E" and so on. The indent-relative function is what will move the cursor to the next word. Emacs will insert a combination of TABs and spaces, or else just spaces, depending on another setting.

If the TAB key isn't bound to indent-relative or indent-relative-maybe, it might (and can be) bound to tab-to-tab-stop instead. tab-to-tab-stop will automatically kick in if indent-relative can't find where to indent next. tab-to-tab-stop is a function that says "check a list called tab-stop-list, and move the cursor to the next position on that list". On my system, tab-to-tab-stop is set at (8, 16, 24, 32, 40, 48, ...), but you don't have to set this as multiples of a common factor. If you wanted, you could set them to prime numbers: (3, 5, 7, 11, 13, 17, 19, 23, ...).

If the tab-to-tab-stop function is invoked, then Emacs will enter however many TABs and spaces are needed to reach the next position on that list. The number of TABs it will enter with each keypress depends on the value of the tab-width variable.

For this session, change the list of tab stops:

M-x edit-tab-stops

For more info on the tab stop list:

M-x describe-variable<RET> tab-stop-list

Just remember that you can edit the tab-stop-list all you want, but if the TAB key is bound to indent-relative or to indent-relative-maybe, editing that list probably won't do what you want. You may prefer to disable indent-relative and enable the tab-to-tab-stop function instead, which will insert TABs or spaces (or both) to a predefined list of places to stop at.

For this session, use tab-to-tab-stop to control TAB behavior:

M-x local-set-key<RET> <TAB> tab-to-tab-stop

Permanently use tab-to-tab-stop to control TAB behavior:

(global-set-key (kbd "TAB") 'tab-to-tab-stop);           # in every mode
OR
(define-key text-mode-map (kbd "TAB") 'tab-to-tab-stop); # only in text-mode

As in the section above, you can modify the "text-mode-map" to be some other mode instead.

Emacs isn't inserting anything!!

If you feel like I do, you probably are considering this a fault. You keep pressing the TAB key, but nothing happens.

In programming modes, such as when you're editing C or Perl or Lisp source code, the TAB key is bound to special indentation rules. That is, instead of being bound to indent-relative as in text-mode, the TAB key is pre-bound to cc-indent-line or lisp-indent-line (if editing your .emacs file), and so on. In c-mode, pressing the TAB key will move the cursor to the first indentation level, and then may not move the cursor forward after that, no matter how many times you press it.

If this behavior isn't what you want, you can do one of these things:

  • Press Ctrl-q <TAB> to insert a TAB character right now
  • Temporarily reassign the TAB key to self-insert-command while staying in the same editing mode
  • Switch to a different editing mode for this session; the TAB behavior will change with the editing mode
  • Change your .emacs file to permanently change the editing mode for the filetype you're using now


What should be inserted when I press TAB?

True tab characters only

To insert only one TAB when the TAB key is pressed:

Back up to read Inserting one thing only

To insert one or more TABS (but never spaces!) when the TAB key is pressed:

In a programming mode, multiple TABS are normally entered when you press the TAB key only once. If you're 3 brace levels deep, the default editing mode will usually enter the number of TAB characters you need to match the current indentation.

In text-mode, this is harder because indent-relative is usually and the indent-relative variable may want to move the cursor ahead to (say) column 11. But if you have the tab-width variable set to 8 characters, there's no way to reach column 11 without adding spaces. The only way to add only multiple TABs with one press of the TAB key (that I can think of) is this:

  • Use tab-to-tab-stop instead of indent-relative to control indent decisions.
  • Set the tab-width variable to a number you like (say, 4)
  • Set each item in the tab-stop-list to a multiple of that number (say, "4, 8, 16, 24" etc.)

Spaces only

For this session, force Emacs to indent with spaces, never with TABs:

M-x set-variable<RET> indent-tabs-mode<RET> nil

Permanently force Emacs to indent with spaces, never with TABs:

(setq-default indent-tabs-mode nil);     # put this in your .emacs file

For this file, force Emacs to indent with spaces, never with TABs:

Insert the following command into line #1 of your file. Read the following section for details on file-specific variables.

-*-  indent-tabs-mode:nil;  -*-

Setting file-specific variables for Emacs

Emacs is designed so that individual preferences can be customized on a per-file basis, even superseding customizations based on filetype or file extensions. To accomplish this, the customizations must be inserted either in line #1 of the file, or else at the very bottom of the file (less than 3000 characters from the end). These customizations are called "File variables", and you can read much more about them by running the Emacs command:
Ctrl-h i mEmacs<RET> gFile Variables<RET>

I like to put the variables on the top line of the file, but you can put them at the end of the file if you prefer. On the top line of the file, you put the variables between two -*- symbols, like this:

              -*-  variable:value; variable:value; ...      -*-

You may separate multiple variables with semicolons (;). If you are using a programming language, you may prefix a comment string to the start, like so:

   <?php   //  -*- mode:php; tab-width:3; intent-tabs-mode:nil;  -*-
   //
   // Double-slashes begin comments in PHP

Insert a combination of TABs and spaces

For this session, allow Emacs to use both TABs and spaces to indent:

M-x set-variable<RET> indent-tabs-mode<RET> t
; You only need this if the default has been turned off

Permanently set Emacs to use both TABs and spaces to indent:

(setq-default indent-tabs-mode t);     # put this in your .emacs file
; Since this is the default, you shouldn't need to add this command.

For this file, use both TABs and spaces to indent:

-*-  indent-tabs-mode:t;  -*-          # put this on line #1 of the fiile
                                       # more about using File Variables

The default behavior of Emacs is to use both TABs and spaces to reach the next stop position. This is controlled by a Boolean variable, indent-tabs-mode. If the variable is t (True), Emacs will insert both TABs and spaces to indent. If the variable is nil (False), Emacs will insert only spaces to do its indentation.

The indent-tabs-mode variable answers a what question, namely, What can I use to indent? But along with this, Emacs also answers a when question, When does pressing the TAB key do something unusual?, and also a how far question, which is How far ahead should the next stop position be?

The when question is controlled by the editing modes (e.g., Lisp-mode), which have different settings for each mode. The how far? question is addressed by indent-relative or by indent-relative-maybe or by tab-to-tab-stop. These are three variables (or rules, if you like), and Emacs uses these rules to figure out how far to move the cursor forward, using the smallest number of TABs and spaces needed to reach that next position.

If you don't like this behavior and want to change it, look at one of the tabs only or spaces only options just above.

If you used to have this behavior and want to get it back, then you're probably in a special editing mode like Lisp-mode, outline-mode, or something else. Try typing M-x text-mode to switch back to a more familiar editing mode.



How wide should TAB spacing display?

Every 8 characters

What is a TAB? A tab is an invisible one-byte character that tells the screen to display the next character a certain number of characters to the right. It doesn't have to be capitalized, so "tab" is an acceptable spelling. A TAB can also represent the plastic "TAB key" on the computer keyboard, which often does not insert a literal TAB character into the file or the command line. For the rest of this essay, when I refer to the TAB, I mean the invisible one-byte character that controls the placement of characters sent to the screen or the printer. If I put a space (which incidentally is also an invisible one-byte character) between the letters A and B, I expect to see something like this:

0123456789X12
   A B
-------------

But if I put a TAB between the letters C and D, then I should expect to see the letter D shifted to the right several characters more, which is what normally happens. In particular, note that in the example below, there is only one TAB character between C and D and between E and F, even though the spacing is visually different to us:

0123456789X12
   C    D
 E      F
-------------

The default TAB display is every eight characters. This means that when you have a TAB character somewhere in a line, the character following that character will appear in a mathematically predictable position on the line. If the first character on your line is position 0 (zero), like in Emacs, then the next character after a TAB will either be on 8, 16, 24, 32, 40, or in some other number which is a multiple of 8.

Looking at a line with true TABs in it, it may appear as if there are multiple spaces present on the line, but in fact there are not. The tab-width variable expands the TAB characters on the line to stop at the next unit of i × 8, where i is a positive integer. So therefore, the TAB "stops" occur at positions 8, 16, 24, 32, 40, and so forth.

Some people may find it helpful to use whitespace-mode, an Emacs minor mode designed to display TABs and/or spaces in a different highlighted color. whitespace-mode has been part of Emacs since version 23. See a sample use on this page.

If your version of Emacs is prior to version 23, get the Emacs Lisp source here for Version 21 or 22:

http://www.emacswiki.org/emacs/WhiteSpace

After installation, type M-x whitespace-mode to toggle the display of TABS and spaces on and off. You can also control the background color and other features.

Every N characters

This is done by changing the value of the tab-width variable. Note that this has the effect not only of altering how lines with TABs are displayed on the console, but also of altering how many TAB characters are inserted by the tab-to-tab-stop and the indent-relative commands (that is, if you permit TABs to be inserted by the two previous commands. You can enable those commands and permit only spaces to be inserted by them, you know . . .).

For this session, set the tab-width to 7 characters

M-x set-variable<RET> tab-width<RET> 7

Permanently set the default tab-width to 7 characters

(setq default-tab-width 7);     # add this to your .emacs file

For this file, set the tab-width to 7 characters

-*-  tab-width:7  -*-           # put this on line #1 of the fiile
                                # more about using File Variables

Display a certain number of inches or cm. from the left

Emacs isn't Microsoft Word, and therefore it doesn't permit you to set things like font-size, point-size, page layout, and other things that word-processing programs may permit you to do. Emacs is a text editor, and therefore it counts things in characters, not inches or centimeters.

In short, you can't tell Emacs to "indent the first line of each paragraph one-half inch," like you can in Microsoft Word.

You can tell Emacs what fonts and what font-size you want to see on your computer screen. But this doesn't affect how those fonts are printed on paper. Further, you may be thinking of a TAB as a series of (say) half-inch indentations. Emacs doesn't think that way. It thinks of TAB as a thing which is N-characters wide, and exactly how wide the N will display is up to you. If you want N to display at every 5 characters, you can do that. If you want N to be shown every 13 characters, you can do that, too.

The notion of Display-This-On-The-Screen is not the same as how many characters to insert when the TAB key is pressed. Pressing the TAB key inserts a certain number of (TABs|spaces|both) into the document. But showing you true TABs on screen is another issue. The tabs you see may just look like consecutive spaces, but really they are a single character which is set to display every N characters wide. Usually the N is 8 characters, but you can set Emacs up do display a different multiple of characters instead.



Tabify: Change spaces to TABs

The Emacs command M-x tabify will remove space characters and insert TABs, effectively making the file smaller. Tabify only works on a marked region, not on the whole buffer. (A "region" is the area or block of text between the "point" and the "mark" in Emacs.)

tabify uses the current tab-width variable to calculate how many tabs to insert on the line. For example, if you have 5 spaces at the beginning of the line and the tab-width variable is set to '2', tabify will change those 5 spaces to 2 TABs and one space. If the tab-width variable is set to '4', tabify will change those 5 spaces to one TAB and one space.

Note in particular that tabify will insert TABs throughout the entire line, not just in the spaces at the beginning of the line. If for some reason you only want TABs inserted at the beginning of a line, but no TABs inserted in the spaces after the line starts, use the Emacs command M-x shell-command-on-region, invoking the external GNU utility called "unexpand", which by default only converts spaces to TABs at the beginning of a line, but not within the line. The "unexpand" utility also supports a switch to alter the length of a TAB character.

Untabify: Change TABs to spaces

The Emacs command M-x untabify will change all the TABs in the current region to spaces. This means you must have marked the region first. A "region" is the area between the "point" (cursor) and the "mark", considered as a stream-block rather than a vertical or columnar block.

How many spaces are inserted for each TAB depends on the current tab-width setting, so if the code doesn't seem to be lining up properly, change the tab-width setting to different values until you find one that looks the most nearly correct, and then invoke untabify to convert all the TABs in the marked region to space characters.

Incidentally, the external GNU utility "expand" also converts TABs to spaces, and it has switches to alter the tab-width value, plus a switch to convert TABs to spaces only at the beginning of the line, but not to touch TAB characters in the middle of a line. This is a very useful utility in some circumstances, such as in editing TAB-delimited data files.



These pages created with GNU Emacs, xhtmlpp, Take Command, and Altap Salamander. Icons courtesy of Qbullets
Last modified: 2015-05-17