23.8. Outline Mode

Outline mode is a major mode much like Text mode but intended for editing outlines. It allows you to make parts of the text temporarily invisible so that you can see the outline structure. Type M-x outline-mode to switch to Outline mode as the major mode of the current buffer.

When Outline mode makes a line invisible, the line does not appear on the screen. The screen appears exactly as if the invisible line were deleted, except that an ellipsis (three periods in a row) appears at the end of the previous visible line (only one ellipsis no matter how many invisible lines follow).

Editing commands that operate on lines, such as C-n and C-p, treat the text of the invisible line as part of the previous visible line. Killing an entire visible line, including its terminating newline, really kills all the following invisible lines along with it.

Outline minor mode provides the same commands as the major mode, Outline mode, but you can use it in conjunction with other major modes. Type M-x outline-minor-mode to enable the Outline minor mode in the current buffer. You can also specify this in the text of a file, with a file local variable of the form mode: outline-minor (Section 32.2.5).

The major mode, Outline mode, provides special key bindings on the C-c prefix. Outline minor mode provides similar bindings with C-c @ as the prefix; this is to reduce the conflicts with the major mode's special commands. (The variable outline-minor-mode-prefix controls the prefix used.)

Entering Outline mode runs the hook text-mode-hook followed by the hook outline-mode-hook (Section 32.2.3).

23.8.1. Format of Outlines

Outline mode assumes that the lines in the buffer are of two types: heading lines and body lines. A heading line represents a topic in the outline. Heading lines start with one or more stars; the number of stars determines the depth of the heading in the outline structure. Thus, a heading line with one star is a major topic; all the heading lines with two stars between it and the next one-star heading are its subtopics; and so on. Any line that is not a heading line is a body line. Body lines belong with the preceding heading line. Here is an example:

* Food
This is the body,
which says something about the topic of food.

** Delicious Food
This is the body of the second-level header.

** Distasteful Food
This could have
a body too, with
several lines.

*** Dormitory Food

* Shelter
Another first-level topic with its header line.

A heading line together with all following body lines is called collectively an entry. A heading line together with all following deeper heading lines and their body lines is called a subtree.

You can customize the criterion for distinguishing heading lines by setting the variable outline-regexp. Any line whose beginning has a match for this regexp is considered a heading line. Matches that start within a line (not at the left margin) do not count. The length of the matching text determines the level of the heading; longer matches make a more deeply nested level. Thus, for example, if a text formatter has commands @chapter, @section and @subsection to divide the document into chapters and sections, you could make those lines count as heading lines by setting outline-regexp to "@chap\\|@\\(sub\\)*section". Note the trick: the two words chapter and section are equally long, but by defining the regexp to match only chap we ensure that the length of the text matched on a chapter heading is shorter, so that Outline mode will know that sections are contained in chapters. This works as long as no other command starts with @chap.

It is possible to change the rule for calculating the level of a heading line by setting the variable outline-level. The value of outline-level should be a function that takes no arguments and returns the level of the current heading. Some major modes such as C, Nroff, and Emacs Lisp mode set this variable in order to work with Outline minor mode.

23.8.2. Outline Motion Commands

Outline mode provides special motion commands that move backward and forward to heading lines.

C-c C-n

Move point to the next visible heading line (outline-next-visible-heading).

C-c C-p

Move point to the previous visible heading line (outline-previous-visible-heading).

C-c C-f

Move point to the next visible heading line at the same level as the one point is on (outline-forward-same-level).

C-c C-b

Move point to the previous visible heading line at the same level (outline-backward-same-level).

C-c C-u

Move point up to a lower-level (more inclusive) visible heading line (outline-up-heading).

C-c C-n (outline-next-visible-heading) moves down to the next heading line. C-c C-p (outline-previous-visible-heading) moves similarly backward. Both accept numeric arguments as repeat counts. The names emphasize that invisible headings are skipped, but this is not really a special feature. All editing commands that look for lines ignore the invisible lines automatically.

More powerful motion commands understand the level structure of headings. C-c C-f (outline-forward-same-level) and C-c C-b (outline-backward-same-level) move from one heading line to another visible heading at the same depth in the outline. C-c C-u (outline-up-heading) moves backward to another heading that is less deeply nested.

23.8.3. Outline Visibility Commands

The other special commands of outline mode are used to make lines visible or invisible. Their names all start with hide or show. Most of them fall into pairs of opposites. They are not undoable; instead, you can undo right past them. Making lines visible or invisible is simply not recorded by the undo mechanism.

C-c C-t

Make all body lines in the buffer invisible (hide-body).

C-c C-a

Make all lines in the buffer visible (show-all).

C-c C-d

Make everything under this heading invisible, not including this heading itself3 (hide-subtree).

C-c C-s

Make everything under this heading visible, including body, subheadings, and their bodies (show-subtree).

C-c C-l

Make the body of this heading line, and of all its subheadings, invisible (hide-leaves).

C-c C-k

Make all subheadings of this heading line, at all levels, visible (show-branches).

C-c C-i

Make immediate subheadings (one level down) of this heading line visible (show-children).

C-c C-c

Make this heading line's body invisible (hide-entry).

C-c C-e

Make this heading line's body visible (show-entry).

C-c C-q

Hide everything except the top n levels of heading lines (hide-sublevels).

C-c C-o

Hide everything except for the heading or body that point is in, plus the headings leading up from there to the top level of the outline (hide-other).

Two commands that are exact opposites are C-c C-c (hide-entry) and C-c C-e (show-entry). They are used with point on a heading line, and apply only to the body lines of that heading. Subheadings and their bodies are not affected.

Two more powerful opposites are C-c C-d (hide-subtree) and C-c C-s (show-subtree). Both expect to be used when point is on a heading line, and both apply to all the lines of that heading's subtree: its body, all its subheadings, both direct and indirect, and all of their bodies. In other words, the subtree contains everything following this heading line, up to and not including the next heading of the same or higher rank.

Intermediate between a visible subtree and an invisible one is having all the subheadings visible but none of the body. There are two commands for doing this, depending on whether you want to hide the bodies or make the subheadings visible. They are C-c C-l (hide-leaves) and C-c C-k (show-branches).

A little weaker than show-branches is C-c C-i (show-children). It makes just the direct subheadings visible--those one level down. Deeper subheadings remain invisible, if they were invisible.

Two commands have a blanket effect on the whole file. C-c C-t (hide-body) makes all body lines invisible, so that you see just the outline structure. C-c C-a (show-all) makes all lines visible. These commands can be thought of as a pair of opposites even though C-c C-a applies to more than just body lines.

The command C-c C-q (hide-sublevels) hides all but the top level headings. With a numeric argument n, it hides everything except the top n levels of heading lines.

The command C-c C-o (hide-other) hides everything except the heading or body text that point is in, plus its parents (the headers leading up from there to top level in the outline).

You can turn off the use of ellipses at the ends of visible lines by setting selective-display-ellipses to nil. Then there is no visible indication of the presence of invisible lines.

23.8.4. Viewing One Outline in Multiple Views

You can display two views of a single outline at the same time, in different windows. To do this, you must create an indirect buffer using M-x make-indirect-buffer. The first argument of this command is the existing outline buffer name, and its second argument is the name to use for the new indirect buffer. Section 17.6.

Once the indirect buffer exists, you can display it in a window in the normal fashion, with C-x 4 b or other Emacs commands. The Outline mode commands to show and hide parts of the text operate on each buffer independently; as a result, each buffer can have its own view. If you want more than two views on the same outline, create additional indirect buffers.