allout.el 166 KB
Newer Older
Richard M. Stallman's avatar
Richard M. Stallman committed
1
;;; allout.el --- Extensive outline mode for use alone and with other modes.
2

3
;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
Richard M. Stallman's avatar
Richard M. Stallman committed
4

5 6 7
;; Author: Ken Manheimer <klm@nist.gov>
;; Maintainer: Ken Manheimer <klm@nist.gov>
;; Created: Dec 1991 - first release to usenet
8
;; Version: Id: allout.el,v 4.3 1994/05/12 17:43:08 klm Exp ||
9
;; Keywords: outline mode
Richard M. Stallman's avatar
Richard M. Stallman committed
10 11 12

;; This file is part of GNU Emacs.

13 14 15 16 17
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

Richard M. Stallman's avatar
Richard M. Stallman committed
18
;; GNU Emacs is distributed in the hope that it will be useful,
19 20 21 22 23
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
Erik Naggum's avatar
Erik Naggum committed
24 25 26
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
Richard M. Stallman's avatar
Richard M. Stallman committed
27

28 29 30 31 32 33 34 35 36 37 38
;;;_* Commentary:

;; Allout outline mode provides extensive outline formatting and
;; manipulation capabilities, subsuming and well beyond that of
;; standard emacs outline mode.  It is specifically aimed at
;; supporting outline structuring and manipulation of syntax-
;; sensitive text, eg programming languages.  (For an example, see the
;; allout code itself, which is organized in outline structure.)
;; 
;; It also includes such things as topic-oriented repositioning, cut, and
;; paste; integral outline exposure-layout; incremental search with
39
;; dynamic exposure/concealment of concealed text; automatic topic-number
40 41 42 43 44 45
;; maintenance; and many other features.
;; 
;; See the docstring of the variables `outline-layout' and
;; `outline-auto-activation' for details on automatic activation of
;; allout outline-mode as a minor mode.  (It has changed since allout
;; 3.x, for those of you that depend on the old method.)
46
;;
47 48 49
;; Note - the lines beginning with ';;;_' are outline topic headers.
;;        Just 'ESC-x eval-current-buffer' to give it a whirl.

50 51 52 53 54 55 56 57 58
;;Ken Manheimer	      				   301 975-3539
;;ken.manheimer@nist.gov			   FAX: 301 963-9137
;;
;;Computer Systems and Communications Division
;;
;;		Nat'l Institute of Standards and Technology
;;		Technology A151
;;		Gaithersburg, MD 20899

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
;;;_* Provide
(provide 'outline)
(provide 'allout)

;;;_* USER CUSTOMIZATION VARIABLES:

;;;_ + Layout, Mode, and Topic Header Configuration

;;;_  = outline-auto-activation
(defvar outline-auto-activation nil
  "*Regulates auto-activation modality of allout outlines - see `outline-init'.

Setq-default by `outline-init' to regulate whether or not allout
outline mode is automatically activated when the buffer-specific
variable `outline-layout' is non-nil, and whether or not the layout
dictated by `outline-layout' should be imposed on mode activation.

With value `t', auto-mode-activation and auto-layout are enabled.
\(This also depends on `outline-find-file-hooks' being installed in
`find-file-hooks', which is also done by `outline-init'.)

With value `ask', auto-mode-activation is enabled, and endorsement for
performing auto-layout is asked of the user each time.

With value `activate', only auto-mode-activation is enabled, auto-
layout is not.

With value `nil', neither auto-mode-activation nor auto-layout are
enabled.

See the docstring for `outline-init' for the proper interface to
this variable.")
;;;_  = outline-layout
(defvar outline-layout nil
  "*Layout specification and provisional mode trigger for allout outlines.
Richard M. Stallman's avatar
Richard M. Stallman committed
94

95 96 97 98 99 100 101 102 103 104 105 106 107
Buffer-specific.

A list value specifies a default layout for the current buffer, to be
applied upon activation of allout outline-mode.  Any non-nil value
will automatically trigger allout outline-mode, provided `outline-
init' has been called to enable it.

See the docstring for `outline-init' for details on setting up for
auto-mode-activation, and for `outline-expose-topic' for the format of
the layout specification.

You can associate a particular outline layout with a file by setting
this var via the file's local variables.  For example, the following
108
lines at the bottom of an Emacs Lisp file:
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123

;;;Local variables:
;;;outline-layout: \(0 : -1 -1 0\)
;;;End:

will, modulo the above-mentioned conditions, cause the mode to be
activated when the file is visited, followed by the equivalent of
`\(outline-expose-topic 0 : -1 -1 0\)'.  \(This is the layout used for
the allout.el, itself.)

Also, allout's mode-specific provisions will make topic prefixes
default to the comment-start string, if any, of the language of the
file.  This is modulo the setting of `outline-use-mode-specific-
leader', which see.") 
(make-variable-buffer-local 'outline-layout)
Richard M. Stallman's avatar
Richard M. Stallman committed
124

125
;;;_  = outline-header-prefix
Richard M. Stallman's avatar
Richard M. Stallman committed
126
(defvar outline-header-prefix "."
127 128 129
  "*Leading string which helps distinguish topic headers.

Outline topic header lines are identified by a leading topic
130 131
header prefix, which mostly have the value of this var at their front.
\(Level 1 topics are exceptions.  They consist of only a single
132 133
character, which is typically set to the outline-primary-bullet.  Many
outlines start at level 2 to avoid this discrepancy.")
Richard M. Stallman's avatar
Richard M. Stallman committed
134
(make-variable-buffer-local 'outline-header-prefix)
135 136
;;;_  = outline-primary-bullet
(defvar outline-primary-bullet "*"
137 138 139
  "Bullet used for top-level outline topics.

Outline topic header lines are identified by a leading topic header
140 141 142
prefix, which is concluded by bullets that includes the value of this
var and the respective outline-*-bullets-string vars.

143
The value of an asterisk ('*') provides for backwards compatibility
144 145 146
with the original emacs outline mode.  See outline-plain-bullets-string
and outline-distinctive-bullets-string for the range of available
bullets.")
Richard M. Stallman's avatar
Richard M. Stallman committed
147
(make-variable-buffer-local 'outline-primary-bullet)
148 149 150
;;;_  = outline-plain-bullets-string
(defvar outline-plain-bullets-string (concat outline-primary-bullet
					     "+-:.;,")
151 152 153
  "*The bullets normally used in outline topic prefixes.

See 'outline-distinctive-bullets-string' for the other kind of
154
bullets.
Richard M. Stallman's avatar
Richard M. Stallman committed
155

156
DO NOT include the close-square-bracket, ']', as a bullet.
Richard M. Stallman's avatar
Richard M. Stallman committed
157

158 159
Outline mode has to be reactivated in order for changes to the value
of this var to take effect.")
Richard M. Stallman's avatar
Richard M. Stallman committed
160
(make-variable-buffer-local 'outline-plain-bullets-string)
161 162
;;;_  = outline-distinctive-bullets-string
(defvar outline-distinctive-bullets-string "=>([{}&!?#%\"X@$~\\"
163
  "*Persistent outline header bullets used to distinguish special topics.
Richard M. Stallman's avatar
Richard M. Stallman committed
164

165 166 167 168
These bullets are not offered among the regular, level-specific
rotation, and are not altered by automatic rebulleting, as when
shifting the level of a topic.  See `outline-plain-bullets-string' for
the selection of alternating bullets.
Richard M. Stallman's avatar
Richard M. Stallman committed
169

170
You must run 'set-outline-regexp' in order for changes
171 172 173 174
to the value of this var to effect outline-mode operation.

DO NOT include the close-square-bracket, ']', on either of the bullet
strings.")
Richard M. Stallman's avatar
Richard M. Stallman committed
175 176
(make-variable-buffer-local 'outline-distinctive-bullets-string)

177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
;;;_  = outline-use-mode-specific-leader
(defvar outline-use-mode-specific-leader t
  "*When non-nil, use mode-specific topic-header prefixes.

Allout outline mode will use the mode-specific `outline-mode-leaders'
and/or comment-start string, if any, to lead the topic prefix string,
so topic headers look like comments in the programming language. 

String values are used as they stand.

Value `t' means to first check for assoc value in `outline-mode-leaders'
alist, then use comment-start string, if any, then use default \(`.').
\(See note about use of comment-start strings, below.\)

Set to the symbol for either of `outline-mode-leaders' or
`comment-start' to use only one of them, respectively.

Value `nil' means to always use the default \(`.'\).

comment-start strings that do not end in spaces are tripled, and an
'_' underscore is tacked on the end, to distinguish them from regular
comment strings.  comment-start strings that do end in spaces are not
tripled, but an underscore is substituted for the space.  \[This
presumes that the space is for appearance, not comment syntax.  You
can use `outline-mode-leaders' to override this behavior, when
incorrect.\]")
;;;_  = outline-mode-leaders
(defvar outline-mode-leaders '()
  "Specific outline-prefix leading strings per major modes.

Entries will be used in the stead (or lieu) of mode-specific
comment-start strings.  See also `outline-use-mode-specific-leader'.

If you're constructing a string that will comment-out outline
structuring so it can be included in program code, append an extra
character, like an \"_\" underscore, to distinguish the lead string
from regular comments that start at bol.")

215
;;;_  = outline-old-style-prefixes
Richard M. Stallman's avatar
Richard M. Stallman committed
216
(defvar outline-old-style-prefixes nil
217 218 219
  "*When non-nil, use only old-and-crusty outline-mode '*' topic prefixes.

Non-nil restricts the topic creation and modification
220 221
functions to asterix-padded prefixes, so they look exactly
like the original emacs-outline style prefixes.
Richard M. Stallman's avatar
Richard M. Stallman committed
222

223 224
Whatever the setting of this variable, both old and new style prefixes
are always respected by the topic maneuvering functions.")
Richard M. Stallman's avatar
Richard M. Stallman committed
225
(make-variable-buffer-local 'outline-old-style-prefixes)
226
;;;_  = outline-stylish-prefixes - alternating bullets
227
(defvar outline-stylish-prefixes t
228
  "*Do fancy stuff with topic prefix bullets according to level, etc.
229

230 231 232 233 234 235 236
Non-nil enables topic creation, modification, and repositioning
functions to vary the topic bullet char (the char that marks the topic
depth) just preceding the start of the topic text) according to level.
Otherwise, only asterisks ('*') and distinctive bullets are used.

This is how an outline can look (but sans indentation) with stylish
prefixes:
237 238 239 240 241

    * Top level
    .* A topic
    . + One level 3 subtopic
    .  . One level 4 subtopic
242
    .  . A second 4 subtopic
243
    . + Another level 3 subtopic
244 245 246 247
    .  #1 A numbered level 4 subtopic
    .  #2 Another
    .  ! Another level 4 subtopic with a different distinctive bullet
    .  #4 And another numbered level 4 subtopic
248

249 250
This would be an outline with stylish prefixes inhibited (but the
numbered and other distinctive bullets retained):
251 252 253

    * Top level
    .* A topic
254 255 256 257 258 259 260 261
    . * One level 3 subtopic
    .  * One level 4 subtopic
    .  * A second 4 subtopic
    . * Another level 3 subtopic
    .  #1 A numbered level 4 subtopic
    .  #2 Another
    .  ! Another level 4 subtopic with a different distinctive bullet
    .  #4 And another numbered level 4 subtopic
262 263 264 265 266 267 268 269

Stylish and constant prefixes (as well as old-style prefixes) are
always respected by the topic maneuvering functions, regardless of
this variable setting.

The setting of this var is not relevant when outline-old-style-prefixes
is non-nil.")
(make-variable-buffer-local 'outline-stylish-prefixes)
Richard M. Stallman's avatar
Richard M. Stallman committed
270

271 272
;;;_  = outline-numbered-bullet
(defvar outline-numbered-bullet "#"
273 274
  "*String designating bullet of topics that have auto-numbering; nil for none.

275
Topics having this bullet have automatic maintenance of a sibling
276
sequence-number tacked on, just after the bullet.  Conventionally set
277
to \"#\", you can set it to a bullet of your choice.  A nil value
278
disables numbering maintenance.")
279 280 281
(make-variable-buffer-local 'outline-numbered-bullet)
;;;_  = outline-file-xref-bullet
(defvar outline-file-xref-bullet "@"
282 283 284
  "*Bullet signifying file cross-references, for `outline-resolve-xref'.

Set this var to the bullet you want to use for file cross-references.
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
Set it 'nil' if you want to inhibit this capability.")

;;;_ + LaTeX formatting
;;;_  - outline-number-pages
(defvar outline-number-pages nil 
  "*Non-nil turns on page numbering for LaTeX formatting of an outline.")
;;;_  - outline-label-style
(defvar outline-label-style "\\large\\bf"
  "*Font and size of labels for LaTeX formatting of an outline.")
;;;_  - outline-head-line-style
(defvar outline-head-line-style "\\large\\sl "
  "*Font and size of entries for LaTeX formatting of an outline.")
;;;_  - outline-body-line-style
(defvar outline-body-line-style " "
  "*Font and size of entries for LaTeX formatting of an outline.")
;;;_  - outline-title-style
(defvar outline-title-style "\\Large\\bf"
  "*Font and size of titles for LaTeX formatting of an outline.")
;;;_  - outline-title
(defvar outline-title '(or buffer-file-name (current-buffer-name))
  "*Expression to be evaluated to determine the title for LaTeX
formatted copy.")
;;;_  - outline-line-skip
(defvar outline-line-skip ".05cm"
  "*Space between lines for LaTeX formatting of an outline.")
;;;_  - outline-indent
(defvar outline-indent ".3cm"
  "*LaTeX formatted depth-indent spacing.")

;;;_ + Miscellaneous customization

;;;_  = outline-keybindings-list
;;; You have to reactivate outline-mode - '(outline-mode t)' - to
;;; institute changes to this var.
(defvar outline-keybindings-list ()
320 321 322 323 324 325
  "*List of outline-mode key / function bindings.

These bindings will be locally bound on the outline-mode-map.  The
keys will be prefixed by outline-command-prefix, unless the cell
contains a third, no-nil element, in which case the initial string
will be used as is.")
326
(setq outline-keybindings-list
Richard M. Stallman's avatar
Richard M. Stallman committed
327 328
      '(
                                        ; Motion commands:
329 330 331 332 333 334 335 336 337 338
        ("?t" outline-latexify-exposed)
        ("\C-n" outline-next-visible-heading)
        ("\C-p" outline-previous-visible-heading)
        ("\C-u" outline-up-current-level)
        ("\C-f" outline-forward-current-level)
        ("\C-b" outline-backward-current-level)
        ("\C-a" outline-beginning-of-current-entry)
        ("\C-e" outline-end-of-current-entry)
	;;("\C-n" outline-next-line-or-topic)
	;;("\C-p" outline-previous-line-or-topic)
Richard M. Stallman's avatar
Richard M. Stallman committed
339
                                        ; Exposure commands:
340 341 342 343 344
        ("\C-i" outline-show-children)
        ("\C-s" outline-show-current-subtree)
        ("\C-h" outline-hide-current-subtree)
        ("\C-o" outline-show-current-entry)
        ("!" outline-show-all)
Richard M. Stallman's avatar
Richard M. Stallman committed
345
                                        ; Alteration commands:
346 347 348 349 350 351 352
        (" " outline-open-sibtopic)
        ("." outline-open-subtopic)
        ("," outline-open-supertopic)
        ("'" outline-shift-in)
        (">" outline-shift-in)
        ("<" outline-shift-out)
        ("\C-m" outline-rebullet-topic)
353
        ("*" outline-rebullet-current-heading)
354 355 356 357 358
        ("#" outline-number-siblings)
        ("\C-k" outline-kill-line t)
        ("\C-y" outline-yank t)
        ("\M-y" outline-yank-pop t)
        ("\C-k" outline-kill-topic)
Richard M. Stallman's avatar
Richard M. Stallman committed
359
                                        ; Miscellaneous commands:
360 361 362
	("\C-@" outline-mark-topic)
        ("@" outline-resolve-xref)
        ("?c" outline-copy-exposed)))
Richard M. Stallman's avatar
Richard M. Stallman committed
363

364 365 366
;;;_  = outline-command-prefix
(defvar outline-command-prefix "\C-c"
  "*Key sequence to be used as prefix for outline mode command key bindings.")
Richard M. Stallman's avatar
Richard M. Stallman committed
367

368 369 370
;;;_  = outline-enwrap-isearch-mode
(defvar outline-enwrap-isearch-mode t
  "*Set non-nil to enable automatic exposure of concealed isearch targets.
371

372 373
If non-nil, isearch will expose hidden text encountered in the course
of a search, and to reconceal it if the search is continued past it.")
374 375 376

;;;_  = outline-use-hanging-indents
(defvar outline-use-hanging-indents t
377 378 379 380
  "*If non-nil, topic body text auto-indent defaults to indent of the header.
Ie, it is indented to be just past the header prefix.  This is
relevant mostly for use with indented-text-mode, or other situations
where auto-fill occurs.
381 382 383 384 385 386

[This feature no longer depends in any way on the 'filladapt.el'
lisp-archive package.]")
(make-variable-buffer-local 'outline-use-hanging-indents)

;;;_  = outline-reindent-bodies
387 388
(defvar outline-reindent-bodies (if outline-use-hanging-indents
				    'text)
389
  "*Non-nil enables auto-adjust of topic body hanging indent with depth shifts.
Richard M. Stallman's avatar
Richard M. Stallman committed
390

391 392 393 394 395 396 397 398
When active, topic body lines that are indented even with or beyond
their topic header are reindented to correspond with depth shifts of
the header.

A value of `t' enables reindent in non-programming-code buffers, ie
those that do not have the variable `comment-start' set.  A value of
`force' enables reindent whether or not `comment-start' is set.")

399
(make-variable-buffer-local 'outline-reindent-bodies)
400 401 402

;;;_  = outline-inhibit-protection
(defvar outline-inhibit-protection nil
403 404 405 406 407
  "*Non-nil disables warnings and confirmation-checks for concealed-text edits.

Outline mode uses emacs change-triggered functions to detect unruly
changes to concealed regions.  Set this var non-nil to disable the
protection, potentially increasing text-entry responsiveness a bit.
408

409 410
This var takes effect at outline-mode activation, so you may have to
deactivate and then reactivate the mode if you want to toggle the
411 412
behavior.")

413
;;;_* CODE - no user customizations below.
414

415 416 417 418
;;;_ #1  Internal Outline Formatting and Configuration
;;;_  - Version
;;;_   = outline-version
(defvar outline-version
419
  (let ((rcs-rev "Revision: 4.3"))
420 421
    (condition-case err
	(save-match-data
422
	  (string-match "Revision: \\([0-9]+\\.[0-9]+\\)" rcs-rev)
423 424
	  (substring rcs-rev (match-beginning 1) (match-end 1)))
      (error rcs-rev)))
425
  "Revision number of currently loaded outline package.  \(allout.el)")
426 427 428 429 430 431 432 433
;;;_   > outline-version
(defun outline-version (&optional here)
  "Return string describing the loaded outline version."
  (interactive "P")
  (let ((msg (concat "Allout Outline Mode v " outline-version)))
    (if here (insert-string msg))
    (message "%s" msg)
    msg))
434 435
;;;_  - Topic header format
;;;_   = outline-regexp
Richard M. Stallman's avatar
Richard M. Stallman committed
436
(defvar outline-regexp ""
437
  "*Regular expression to match the beginning of a heading line.
438

439 440 441
Any line whose beginning matches this regexp is considered a
heading.  This var is set according to the user configuration vars
by set-outline-regexp.")
Richard M. Stallman's avatar
Richard M. Stallman committed
442
(make-variable-buffer-local 'outline-regexp)
443
;;;_   = outline-bullets-string
Richard M. Stallman's avatar
Richard M. Stallman committed
444
(defvar outline-bullets-string ""
445 446 447 448
  "A string dictating the valid set of outline topic bullets.

This var should *not* be set by the user - it is set by 'set-outline-regexp',
and is produced from the elements of 'outline-plain-bullets-string'
449
and 'outline-distinctive-bullets-string'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
450
(make-variable-buffer-local 'outline-bullets-string)
451 452 453 454 455
;;;_   = outline-bullets-string-len
(defvar outline-bullets-string-len 0
  "Length of current buffers' outline-plain-bullets-string.")
(make-variable-buffer-local 'outline-bullets-string-len)
;;;_   = outline-line-boundary-regexp
Richard M. Stallman's avatar
Richard M. Stallman committed
456
(defvar outline-line-boundary-regexp ()
457 458
  "Outline-regexp with outline-style beginning-of-line anchor.

Richard M. Stallman's avatar
Richard M. Stallman committed
459
\(Ie, C-j, *or* C-m, for prefixes of hidden topics).  This is properly
460 461
set when outline-regexp is produced by 'set-outline-regexp', so
that (match-beginning 2) and (match-end 2) delimit the prefix.")
Richard M. Stallman's avatar
Richard M. Stallman committed
462
(make-variable-buffer-local 'outline-line-boundary-regexp)
463
;;;_   = outline-bob-regexp
Richard M. Stallman's avatar
Richard M. Stallman committed
464
(defvar outline-bob-regexp ()
465
  "Like outline-line-boundary-regexp, for headers at beginning of buffer.
Richard M. Stallman's avatar
Richard M. Stallman committed
466
\(match-beginning 2) and (match-end 2) delimit the prefix.")
467 468 469
(make-variable-buffer-local 'outline-bob-regexp)
;;;_   = outline-header-subtraction
(defvar outline-header-subtraction (1- (length outline-header-prefix))
470
  "Outline-header prefix length to subtract when computing topic depth.")
471 472 473 474 475 476 477
(make-variable-buffer-local 'outline-header-subtraction)
;;;_   = outline-plain-bullets-string-len
(defvar outline-plain-bullets-string-len (length outline-plain-bullets-string)
  "Length of outline-plain-bullets-string, updated by set-outline-regexp.")
(make-variable-buffer-local 'outline-plain-bullets-string-len)


478
;;;_   X outline-reset-header-lead (header-lead)
Richard M. Stallman's avatar
Richard M. Stallman committed
479
(defun outline-reset-header-lead (header-lead)
480
  "*Reset the leading string used to identify topic headers."
Richard M. Stallman's avatar
Richard M. Stallman committed
481 482 483
  (interactive "sNew lead string: ")
  (setq outline-header-prefix header-lead)
  (setq outline-header-subtraction (1- (length outline-header-prefix)))
484
  (set-outline-regexp))
485
;;;_   X outline-lead-with-comment-string (header-lead)
Richard M. Stallman's avatar
Richard M. Stallman committed
486
(defun outline-lead-with-comment-string (&optional header-lead)
487 488 489 490
  "*Set the topic-header leading string to specified string.

Useful when for encapsulating outline structure in programming
language comments.  Returns the leading string."
Richard M. Stallman's avatar
Richard M. Stallman committed
491 492 493 494 495 496 497 498

  (interactive "P")
  (if (not (stringp header-lead))
      (setq header-lead (read-string
                         "String prefix for topic headers: ")))
  (setq outline-reindent-bodies nil)
  (outline-reset-header-lead header-lead)
  header-lead)
499 500
;;;_   > outline-infer-header-lead ()
(defun outline-infer-header-lead ()
501 502 503 504
  "Determine appropriate `outline-header-prefix'.

Works according to settings of:

505
       `comment-start'
506 507 508 509
       `outline-header-prefix' (default)
       `outline-use-mode-specific-leader'
and    `outline-mode-leaders'.

510 511
Apply this via \(re\)activation of `outline-mode', rather than
invoking it directly."
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
  (let* ((use-leader (and (boundp 'outline-use-mode-specific-leader)
			  (if (or (stringp outline-use-mode-specific-leader)
				  (memq outline-use-mode-specific-leader
					'(outline-mode-leaders
					  comment-start
					  t)))
			      outline-use-mode-specific-leader
			    ;; Oops - garbled value, equate with effect of 't:
			    t)))
	 (leader
	  (cond
	   ((not use-leader) nil)
	   ;; Use the explicitly designated leader:
	   ((stringp use-leader) use-leader)
	   (t (or (and (memq use-leader '(t outline-mode-leaders))
		       ;; Get it from outline mode leaders?
		       (cdr (assq major-mode outline-mode-leaders)))
		  ;; ... didn't get from outline-mode-leaders...
		  (and (memq use-leader '(t comment-start))
		       comment-start
		       ;; Use comment-start, maybe tripled, and with
		       ;; underscore: 
		       (concat
			(if (string= " "
				     (substring comment-start
						(1- (length comment-start))))
			    ;; Use comment-start, sans trailing space:
			    (substring comment-start 0 -1)
			  (concat comment-start comment-start comment-start))
			;; ... and append underscore, whichever:
			"_")))))))
    (if (not leader)
	nil
      (if (string= leader outline-header-prefix)
	  nil				; no change, nothing to do.
	(setq outline-header-prefix leader)
	outline-header-prefix))))
549 550 551 552 553 554 555 556 557 558 559
;;;_   > outline-infer-body-reindent ()
(defun outline-infer-body-reindent ()
  "Determine proper setting for `outline-reindent-bodies'.

Depends on default setting of `outline-reindent-bodies' \(which see)
and presence of setting for `comment-start', to tell whether the
file is programming code."
  (if (and outline-reindent-bodies
	   comment-start
	   (not (eq 'force outline-reindent-bodies)))
      (setq outline-reindent-bodies nil)))
560
;;;_   > set-outline-regexp ()
Richard M. Stallman's avatar
Richard M. Stallman committed
561
(defun set-outline-regexp ()
562 563 564 565
  "Generate proper topic-header regexp form for outline functions.

Works with respect to `outline-plain-bullets-string' and
`outline-distinctive-bullets-string'."
Richard M. Stallman's avatar
Richard M. Stallman committed
566 567 568 569 570 571 572 573

  (interactive)
  ;; Derive outline-bullets-string from user configured components:
  (setq outline-bullets-string "")
  (let ((strings (list 'outline-plain-bullets-string
                       'outline-distinctive-bullets-string))
        cur-string
        cur-len
574
        cur-char
Richard M. Stallman's avatar
Richard M. Stallman committed
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
        cur-char-string
        index
        new-string)
    (while strings
      (setq new-string "") (setq index 0)
      (setq cur-len (length (setq cur-string (symbol-value (car strings)))))
      (while (< index cur-len)
        (setq cur-char (aref cur-string index))
        (setq outline-bullets-string
              (concat outline-bullets-string
                      (cond
                                        ; Single dash would denote a
                                        ; sequence, repeated denotes
                                        ; a dash:
                       ((eq cur-char ?-) "--")
                                        ; literal close-square-bracket
                                        ; doesn't work right in the
                                        ; expr, exclude it:
                       ((eq cur-char ?\]) "")
                       (t (regexp-quote  (char-to-string cur-char))))))
        (setq index (1+ index)))
      (setq strings (cdr strings)))
    )
  ;; Derive next for repeated use in outline-pending-bullet:
  (setq outline-plain-bullets-string-len (length outline-plain-bullets-string))
  (setq outline-header-subtraction (1- (length outline-header-prefix)))
  ;; Produce the new outline-regexp:
  (setq outline-regexp (concat "\\(\\"
                               outline-header-prefix
                               "[ \t]*["
                               outline-bullets-string
                               "]\\)\\|\\"
                               outline-primary-bullet
                               "+\\|\^l"))
  (setq outline-line-boundary-regexp
610
        (concat "\\([\n\r]\\)\\(" outline-regexp "\\)"))
Richard M. Stallman's avatar
Richard M. Stallman committed
611 612 613
  (setq outline-bob-regexp
        (concat "\\(\\`\\)\\(" outline-regexp "\\)"))
  )
614
;;;_  - Key bindings
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
;;;_   = outline-mode-map
(defvar outline-mode-map nil "Keybindings for (allout) outline minor mode.")
;;;_   > produce-outline-mode-map (keymap-alist &optional base-map)
(defun produce-outline-mode-map (keymap-list &optional base-map)
  "Produce keymap for use as outline-mode-map, from keymap-list.

Built on top of optional BASE-MAP, or empty sparse map if none specified.
See doc string for outline-keybindings-list for format of binding list."
  (let ((map (or base-map (make-sparse-keymap))))
    (mapcar (lambda (cell)
	      (apply 'define-key map (if (null (cdr (cdr cell)))
					 (cons (concat outline-command-prefix
						       (car cell))
					       (cdr cell))
				       (list (car cell) (car (cdr cell))))))
	    keymap-list)
    map))
;;;_   = outline-prior-bindings - being deprecated.
633 634 635
(defvar outline-prior-bindings nil 
  "Variable for use in V18, with outline-added-bindings, for
resurrecting, on mode deactivation, bindings that existed before
636 637
activation.  Being deprecated.")
;;;_   = outline-added-bindings - being deprecated
638 639 640
(defvar outline-added-bindings nil 
  "Variable for use in V18, with outline-prior-bindings, for
resurrecting, on mode deactivation, bindings that existed before
641
activation.  Being deprecated.")
642 643
;;;_  - Mode-Specific Variable Maintenance Utilities
;;;_   = outline-mode-prior-settings
Richard M. Stallman's avatar
Richard M. Stallman committed
644
(defvar outline-mode-prior-settings nil
645
  "Internal outline mode use; settings to be resumed on mode deactivation.")
Richard M. Stallman's avatar
Richard M. Stallman committed
646
(make-variable-buffer-local 'outline-mode-prior-settings)
647
;;;_   > outline-resumptions (name &optional value)
Richard M. Stallman's avatar
Richard M. Stallman committed
648 649
(defun outline-resumptions (name &optional value)

650 651 652 653 654 655 656 657
  "Registers or resumes settings over outline-mode activation/deactivation.

First arg is NAME of variable affected.  Optional second arg is list
containing outline-mode-specific VALUE to be imposed on named
variable, and to be registered.  (It's a list so you can specify
registrations of null values.)  If no value is specified, the
registered value is returned (encapsulated in the list, so the caller
can distinguish nil vs no value), and the registration is popped
658
from the list."
Richard M. Stallman's avatar
Richard M. Stallman committed
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676

  (let ((on-list (assq name outline-mode-prior-settings))
        prior-capsule                   ; By 'capsule' i mean a list
                                        ; containing a value, so we can
                                        ; distinguish nil from no value.
        )

    (if value

        ;; Registering:
        (progn
          (if on-list
              nil 	; Already preserved prior value - don't mess with it.
            ;; Register the old value, or nil if previously unbound:
            (setq outline-mode-prior-settings
                  (cons (list name
                              (if (boundp name) (list (symbol-value name))))
                        outline-mode-prior-settings)))
677 678 679
                                        ; And impose the new value, locally:
	  (progn (make-local-variable name)
		 (set name (car value))))
Richard M. Stallman's avatar
Richard M. Stallman committed
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704

      ;; Relinquishing:
      (if (not on-list)

          ;; Oops, not registered - leave it be:
          nil

        ;; Some registration:
                                        ; reestablish it:
        (setq prior-capsule (car (cdr on-list)))
        (if prior-capsule
            (set name (car prior-capsule)) ; Some prior value - reestablish it.
          (makunbound name))		; Previously unbound - demolish var.
                                        ; Remove registration:
        (let (rebuild)
          (while outline-mode-prior-settings
            (if (not (eq (car outline-mode-prior-settings)
                         on-list))
                (setq rebuild
                      (cons (car outline-mode-prior-settings)
                            rebuild)))
            (setq outline-mode-prior-settings
                  (cdr outline-mode-prior-settings)))
          (setq outline-mode-prior-settings rebuild)))))
  )
705
;;;_  - Mode-specific incidentals
706 707
;;;_   = outline-during-write-cue nil
(defvar outline-during-write-cue nil
708
  "Used to inhibit outline change-protection during file write.
709

710 711 712
See also `outline-post-command-business', `outline-write-file-hook',
`outline-before-change-protect', and `outline-post-command-business'
functions.")
713 714
;;;_   = outline-override-protect nil
(defvar outline-override-protect nil
715 716 717
  "Used in outline-mode for regulate of concealed-text protection mechanism.

Allout outline mode regulates alteration of concealed text to protect
718
against inadvertent, unnoticed changes.  This is for use by specific,
719 720
native outline functions to temporarily override that protection.
It's automatically reset to nil after every buffer modification.")
721 722 723
(make-variable-buffer-local 'outline-override-protect)
;;;_   > outline-unprotected (expr)
(defmacro outline-unprotected (expr)
724
  "Evaluate EXPRESSION with `outline-override-protect' let-bound 't'."
725 726 727 728 729
  (` (let ((outline-override-protect t))
       (, expr))))
;;;_   = outline-undo-aggregation
(defvar outline-undo-aggregation 30
  "Amount of successive self-insert actions to bunch together per undo.
730

731 732 733
This is purely a kludge variable, regulating the compensation for a bug in
the way that before-change-function and undo interact.")
(make-variable-buffer-local 'outline-undo-aggregation)
734
;;;_   = file-var-bug hack
735 736 737 738
(defvar outline-v18/9-file-var-hack nil
  "Horrible hack used to prevent invalid multiple triggering of outline
mode from prop-line file-var activation.  Used by outline-mode function
to track repeats.")
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
;;;_   > outline-write-file-hook ()
(defun outline-write-file-hook ()
  "In outline mode, run as a local-write-file-hooks activity.

Currently just sets 'outline-during-write-cue', so outline-change-
protection knows to keep inactive during file write."
  (setq outline-during-write-cue t)
  nil)

;;;_ #2 Mode activation
;;;_  = outline-mode
(defvar outline-mode () "Allout outline mode minor-mode flag.")
(make-variable-buffer-local 'outline-mode)
;;;_  > outline-mode-p ()
(defmacro outline-mode-p ()
  "Return t if outline-mode is active in current buffer."
  'outline-mode)
;;;_  = outline-explicitly-deactivated
(defvar outline-explicitly-deactivated nil
758
  "Outline-mode was last deliberately deactivated.
759 760
So outline-post-command-business should not reactivate it...")
(make-variable-buffer-local 'outline-explicitly-deactivated)
761 762
;;;_  > outline-init (&optional mode)
(defun outline-init (&optional mode)
763 764
  "Prime outline-mode to enable/disable auto-activation, wrt `outline-layout'.

765
MODE is one of the following symbols:
766

767 768 769
 - nil \(or no argument) deactivate auto-activation/layou;
 - 'activate', enable auto-activation only;
 - 'ask', enable auto-activation, and enable auto-layout but with
770
   confirmation for layout operation solicited from user each time;
771 772 773
 - 'report', just report and return the current auto-activation state;
 - anything else \(eg, t) for auto-activation and auto-layout, without
   any confirmation check.
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789

Use this function to setup your emacs session for automatic activation
of allout outline mode, contingent to the buffer-specific setting of
the `outline-layout' variable.  (See `outline-layout' and
`outline-expose-topic' docstrings for more details on auto layout).

`outline-init' works by setting up (or removing) the outline-mode
find-file-hook, and giving `outline-auto-activation' a suitable
setting.

To prime your emacs session for full auto-outline operation, include
the following two lines in your emacs init file:

\(require 'allout)
\(outline-init t)"

790 791
  (interactive)
  (if (interactive-p)
792
      (progn
793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835
	(setq mode
	      (completing-read
	       (concat "Select outline auto setup mode "
		       "(empty for report, ? for options) ")
	       '(("nil")("full")("activate")("deactivate")
		 ("ask") ("report") (""))
	       nil
	       t))
	(if (string= mode "")
	    (setq mode 'report)
	  (setq mode (intern-soft mode)))))
  (let
      ;; convenience aliases, for consistent ref to respective vars:
      ((hook 'outline-find-file-hook)
       (curr-mode 'outline-auto-activation))
	
    (cond ((not mode)
	   (setq find-file-hooks (delq hook find-file-hooks))
	   (if (interactive-p)
	       (message "Allout outline mode auto-activation inhibited.")))
	  ((eq mode 'report)
	   (if (not (memq hook find-file-hooks))
	       (outline-init nil)
	     ;; Just punt and use the reports from each of the modes:
	     (outline-init (symbol-value curr-mode))))
	  (t (add-hook 'find-file-hooks hook)
	     (set curr-mode		; 'set', not 'setq'!
		  (cond ((eq mode 'activate)
			 (message
			  "Outline mode auto-activation enabled.")
			 'activate)
			((eq mode 'report)
			 ;; Return the current mode setting:
			 (outline-init mode))
			((eq mode 'ask)
			 (message
			  (concat "Outline mode auto-activation and "
				  "-layout \(upon confirmation) enabled."))
			 'ask)
			((message
			  "Outline mode auto-activation and -layout enabled.")
			 'full)))))))
		   
836 837
;;;_  > outline-mode (&optional toggle)
;;;_   : Defun:
Richard M. Stallman's avatar
Richard M. Stallman committed
838
(defun outline-mode (&optional toggle)
839
;;;_    . Doc string:
840 841 842 843 844 845 846 847 848 849 850 851
  "Toggle minor mode for controlling exposure and editing of text outlines.

Optional arg forces mode reactivation iff arg is positive num or symbol.

Allout outline mode provides extensive outline formatting and
manipulation capabilities.  It is specifically aimed at supporting
outline structuring and manipulation of syntax-sensitive text, eg
programming languages.  \(For an example, see the allout code itself,
which is organized in outline structure.\)

It also includes such things as topic-oriented repositioning, cut, and
paste; integral outline exposure-layout; incremental search with
852
dynamic exposure/concealment of concealed text; automatic topic-number
853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
maintenance; and many other features.

See the docstring of the variable `outline-init' for instructions on
priming your emacs session for automatic activation of outline-mode,
according to file-var settings of the `outline-layout' variable.

Below is a description of the bindings, and then explanation of
special outline-mode features and terminology.

The bindings themselves are established according to the values of
variables `outline-keybindings-list' and `outline-command-prefix',
each time the mode is invoked.  Prior bindings are resurrected when
the mode is revoked.

	Navigation:				   Exposure Control:
	----------                                 ----------------
C-c C-n outline-next-visible-heading     | C-c C-h outline-hide-current-subtree
C-c C-p outline-previous-visible-heading | C-c C-i outline-show-children
C-c C-u outline-up-current-level         | C-c C-s outline-show-current-subtree
C-c C-f outline-forward-current-level    | C-c C-o outline-show-current-entry
C-c C-b outline-backward-current-level   | ^U C-c C-s outline-show-all
C-c C-e outline-end-of-current-entry     |	   outline-hide-current-leaves
C-c C-a outline-beginning-of-current-entry, alternately, goes to hot-spot

	Topic Header Production:
	-----------------------
C-c<SP>	outline-open-sibtopic	Create a new sibling after current topic.
C-c .	outline-open-subtopic	... an offspring of current topic.
C-c ,	outline-open-supertopic	... a sibling of the current topic's parent.

	Topic Level and Prefix Adjustment:
	---------------------------------
C-c >	outline-shift-in	Shift current topic and all offspring deeper.
C-c <	outline-shift-out	... less deep.
C-c<CR>	outline-rebullet-topic	Reconcile bullets of topic and its' offspring
				- distinctive bullets are not changed, others
				  alternated according to nesting depth.
890
C-c *	outline-rebullet-current-heading Prompt for alternate bullet for
891
					 current topic.
Richard M. Stallman's avatar
Richard M. Stallman committed
892 893 894 895
C-c #	outline-number-siblings	Number bullets of topic and siblings - the
				offspring are not affected.  With repeat
				count, revoke numbering.

896 897 898 899
	Topic-oriented Killing and Yanking:
	----------------------------------
C-c C-k	outline-kill-topic	Kill current topic, including offspring.
C-k	outline-kill-line	Like kill-line, but reconciles numbering, etc.
Richard M. Stallman's avatar
Richard M. Stallman committed
900 901
C-y	outline-yank		Yank, adjusting depth of yanked topic to
				depth of heading if yanking into bare topic
902
				heading (ie, prefix sans text).
Richard M. Stallman's avatar
Richard M. Stallman committed
903 904
M-y	outline-yank-pop	Is to outline-yank as yank-pop is to yank

905 906
	Misc commands:
	-------------
Richard M. Stallman's avatar
Richard M. Stallman committed
907
C-c @   outline-resolve-xref    pop-to-buffer named by xref (cf
908 909 910 911 912 913 914 915 916
				outline-file-xref-bullet)
C-c c	outline-copy-exposed	Copy current topic outline sans concealed
				text, to buffer with name derived from
				current buffer - \"XXX exposed\"
M-x outlineify-sticky		Activate outline mode for current buffer,
				and establish a default file-var setting
				for `outline-layout'.
ESC ESC (outline-init t)	Setup emacs session for outline mode
				auto-activation.
Richard M. Stallman's avatar
Richard M. Stallman committed
917

918
		 HOT-SPOT Operation
919

920 921
Hot-spot operation provides a means for easy, single-keystroke outline
navigation and exposure control.
922

923 924 925 926 927 928 929 930
\\<outline-mode-map>
When the text cursor is positioned directly on the bullet character of
a topic, regular characters (a to z) invoke the commands of the
corresponding outline-mode keymap control chars.  For example, \"f\"
would invoke the command typically bound to \"C-c C-f\"
\(\\[outline-forward-current-level] `outline-forward-current-level').

Thus, by positioning the cursor on a topic bullet, you can execute
931
the outline navigation and manipulation commands with a single
932 933 934
keystroke.  Non-literal chars never get this special translation, so
you can use them to get away from the hot-spot, and back to normal
operation.
935

936
Note that the command `outline-beginning-of-current-entry' \(\\[outline-beginning-of-current-entry]\)
937 938 939
will move to the hot-spot when the cursor is already located at the
beginning of the current entry, so you can simply hit \\[outline-beginning-of-current-entry]
twice in a row to get to the hot-spot.
Richard M. Stallman's avatar
Richard M. Stallman committed
940

941
			    Terminology
Richard M. Stallman's avatar
Richard M. Stallman committed
942

943 944 945 946 947 948
Topic hierarchy constituents - TOPICS and SUBTOPICS:

TOPIC:	A basic, coherent component of an emacs outline.  It can
	contain other topics, and it can be subsumed by other topics,
CURRENT topic:
	The visible topic most immediately containing the cursor.
949 950
DEPTH:	The degree of nesting of a topic; it increases with
	containment.  Also called the:
951 952 953 954 955 956 957
LEVEL:	The same as DEPTH.

ANCESTORS:
	The topics that contain a topic.
PARENT:	A topic's immediate ancestor.  It has a depth one less than
	the topic.
OFFSPRING:
958 959 960
	The topics contained by a topic;
SUBTOPIC:
	An immediate offspring of a topic;
961 962 963
CHILDREN:
	The immediate offspring of a topic.
SIBLINGS:
964 965
	Topics having the same parent and depth.
	       
966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
Topic text constituents:

HEADER:	The first line of a topic, include the topic PREFIX and header
	text. 
PREFIX: The leading text of a topic which which distinguishes it from
	normal text.  It has a strict form, which consists of a
	prefix-lead string, padding, and a bullet.  The bullet may be
	followed by a number, indicating the ordinal number of the
	topic among its siblings, a space, and then the header text.

	The relative length of the PREFIX determines the nesting depth
	of the topic.
PREFIX-LEAD:
	The string at the beginning of a topic prefix, normally a '.'.
	It can be customized by changing the setting of
981
	`outline-header-prefix' and then reinitializing outline-mode.
982 983 984 985

	By setting the prefix-lead to the comment-string of a
	programming language, you can embed outline-structuring in
	program code without interfering with the language processing
986 987
	of that code.  See `outline-use-mode-specific-leader'
	docstring for more detail.
988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
PREFIX-PADDING:
	Spaces or asterisks which separate the prefix-lead and the
	bullet, according to the depth of the topic.
BULLET: A character at the end of the topic prefix, it must be one of
	the characters listed on 'outline-plain-bullets-string' or
        'outline-distinctive-bullets-string'.  (See the documentation
        for these variables for more details.)  The default choice of
	bullet when generating varies in a cycle with the depth of the
	topic.
ENTRY:	The text contained in a topic before any offspring.
BODY:	Same as ENTRY.


EXPOSURE:
 	The state of a topic which determines the on-screen visibility
	of its' offspring and contained text.
CONCEALED:
	Topics and entry text whose display is inhibited.  Contiguous
	units of concealed text is represented by '...' ellipses.
	(Ref the 'selective-display' var.)

	Concealed topics are effectively collapsed within an ancestor.
CLOSED:	A topic whose immediate offspring and body-text is concealed.
1011
OPEN:	A topic that is not closed, though its' offspring or body may be."
1012
;;;_    . Code
Richard M. Stallman's avatar
Richard M. Stallman committed
1013 1014
  (interactive "P")

1015
  (let* ((active (and (not (equal major-mode 'outline))
1016 1017
		     (outline-mode-p)))
				       ; Massage universal-arg 'toggle' val:
1018
	 (toggle (and toggle
1019 1020
		     (or (and (listp toggle)(car toggle))
			 toggle)))
1021
				       ; Activation specifically demanded?
1022
	 (explicit-activation (or
1023 1024 1025 1026 1027
			      ;;
			      (and toggle
				   (or (symbolp toggle)
				       (and (natnump toggle)
					    (not (zerop toggle)))))))
1028 1029
	 ;; outline-mode already called once during this complex command?
	 (same-complex-command (eq outline-v18/9-file-var-hack
1030 1031 1032
				  (car command-history)))
	 do-layout
	 )
1033

1034
				       ; See comments below re v19.18,.19 bug.
1035 1036
    (setq outline-v18/9-file-var-hack (car command-history))

Richard M. Stallman's avatar
Richard M. Stallman committed
1037 1038
    (cond

1039
     ;; Provision for v19.18, 19.19 bug -
1040 1041 1042 1043 1044
     ;; Emacs v 19.18, 19.19 file-var code invokes prop-line-designated
     ;; modes twice when file is visited.  We have to avoid toggling mode
     ;; off on second invocation, so we detect it as best we can, and
     ;; skip everything.
     ((and same-complex-command		; Still in same complex command
1045 1046 1047 1048 1049
				       ; as last time outline-mode invoked.
	  active			; Already activated.
	  (not explicit-activation)	; Prop-line file-vars don't have args.
	  (string-match "^19.1[89]"	; Bug only known to be in v19.18 and
			emacs-version)); 19.19.
1050
      t)
1051 1052
	  
     ;; Deactivation:
1053
     ((and (not explicit-activation)
1054 1055 1056 1057 1058 1059
	  (or active toggle))
				       ; Activation not explicitly
				       ; requested, and either in
				       ; active state or *de*activation
				       ; specifically requested:
      (setq outline-explicitly-deactivated t)
1060
      (if (string-match "^18\." emacs-version)
1061 1062
				       ; Revoke those keys that remain
				       ; as we set them:
1063
	  (let ((curr-loc (current-local-map)))
1064 1065 1066 1067 1068 1069 1070 1071
	   (mapcar '(lambda (cell)
		      (if (eq (lookup-key curr-loc (car cell))
			      (car (cdr cell)))
			  (define-key curr-loc (car cell)
			    (assq (car cell) outline-prior-bindings))))
		   outline-added-bindings)
	   (outline-resumptions 'outline-added-bindings)
	   (outline-resumptions 'outline-prior-bindings)))
1072 1073 1074

      (if outline-old-style-prefixes
	  (progn
1075 1076
	   (outline-resumptions 'outline-primary-bullet)
	   (outline-resumptions 'outline-old-style-prefixes)))
Richard M. Stallman's avatar
Richard M. Stallman committed
1077
      (outline-resumptions 'selective-display)
1078 1079 1080
      (if (and (boundp 'before-change-function) before-change-function)
	  (outline-resumptions 'before-change-function))
      (setq pre-command-hook (delq 'outline-pre-command-business
1081
				  pre-command-hook))
1082
      (setq local-write-file-hooks
1083 1084
	   (delq 'outline-write-file-hook
		 local-write-file-hooks))
Richard M. Stallman's avatar
Richard M. Stallman committed
1085 1086
      (outline-resumptions 'paragraph-start)
      (outline-resumptions 'paragraph-separate)
1087
      (outline-resumptions (if (string-match "^18" emacs-version)
1088 1089
			      'auto-fill-hook
			    'auto-fill-function))
1090
      (outline-resumptions 'outline-former-auto-filler)
Richard M. Stallman's avatar
Richard M. Stallman committed
1091 1092
      (setq outline-mode nil))

1093
     ;; Activation:
Richard M. Stallman's avatar
Richard M. Stallman committed
1094
     ((not active)
1095
      (setq outline-explicitly-deactivated nil)
1096 1097
      (if outline-old-style-prefixes
	  (progn			; Inhibit all the fancy formatting:
1098 1099 1100 1101
	   (outline-resumptions 'outline-primary-bullet '("*"))
	   (outline-resumptions 'outline-old-style-prefixes '(()))))

      (outline-infer-header-lead)
1102
      (outline-infer-body-reindent)
1103

Richard M. Stallman's avatar
Richard M. Stallman committed
1104
      (set-outline-regexp)
1105 1106 1107

				       ; Produce map from current version
				       ; of outline-keybindings-list:
1108 1109 1110
      (if (boundp 'minor-mode-map-alist)

	  (progn			; V19, and maybe lucid and
1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125
				       ; epoch, minor-mode key bindings:
	   (setq outline-mode-map
		 (produce-outline-mode-map outline-keybindings-list))
	   (fset 'outline-mode-map outline-mode-map)
				       ; Include on minor-mode-map-alist,
				       ; if not already there:
	   (if (not (member '(outline-mode . outline-mode-map)
			    minor-mode-map-alist))
	       (setq minor-mode-map-alist
		     (cons '(outline-mode . outline-mode-map)
			   minor-mode-map-alist))))

				       ; V18 minor-mode key bindings:
				       ; Stash record of added bindings
				       ; for later revocation:
1126
	(outline-resumptions 'outline-added-bindings
1127
			    (list outline-keybindings-list))
1128
	(outline-resumptions 'outline-prior-bindings
1129 1130
			    (list (current-local-map)))
				       ; and add them:
1131
	(use-local-map (produce-outline-mode-map outline-keybindings-list
1132
						(current-local-map)))
1133
	)
1134 1135 1136 1137
		 
				       ; selective-display is the
				       ; emacs conditional exposure
				       ; mechanism:
1138 1139 1140 1141
      (outline-resumptions 'selective-display '(t))
      (if outline-inhibit-protection
	  t
	(outline-resumptions 'before-change-function
1142 1143 1144 1145
			    '(outline-before-change-protect)))
				       ; Temporarily set by any outline
				       ; functions that can be trusted to
				       ; deal properly with concealed text.
1146
      (add-hook 'local-write-file-hooks 'outline-write-file-hook)
1147 1148 1149
				       ; Custom auto-fill func, to support
				       ; respect for topic headline,
				       ; hanging-indents, etc:
1150
      (let* ((fill-func-var (if (string-match "^18" emacs-version)
1151 1152 1153
			       'auto-fill-hook
			     'auto-fill-function))
	    (fill-func (symbol-value fill-func-var)))
1154 1155 1156 1157 1158
	;; Register prevailing fill func for use by outline-auto-fill:
	(outline-resumptions 'outline-former-auto-filler (list fill-func))
	;; Register outline-auto-fill to be used if filling is active:
	(outline-resumptions fill-func-var '(outline-auto-fill)))
      ;; Paragraphs are broken by topic headlines.
Richard M. Stallman's avatar
Richard M. Stallman committed
1159 1160
      (make-local-variable 'paragraph-start)
      (outline-resumptions 'paragraph-start
1161
			  (list (concat paragraph-start "\\|\\("
1162
					outline-regexp "\\)")))
Richard M. Stallman's avatar
Richard M. Stallman committed
1163 1164
      (make-local-variable 'paragraph-separate)
      (outline-resumptions 'paragraph-separate
1165
			  (list (concat paragraph-separate "\\|\\("
1166
					outline-regexp "\\)")))
1167 1168 1169

      (or (assq 'outline-mode minor-mode-alist)
	  (setq minor-mode-alist
1170 1171 1172 1173
	       (cons '(outline-mode " Outl") minor-mode-alist)))

      (if outline-layout
	  (setq do-layout t))
Richard M. Stallman's avatar
Richard M. Stallman committed
1174 1175

      (if outline-enwrap-isearch-mode
1176
	  (outline-enwrap-isearch))
1177

Richard M. Stallman's avatar
Richard M. Stallman committed
1178 1179
      (run-hooks 'outline-mode-hook)
      (setq outline-mode t))
1180 1181

     ;; Reactivation:
1182 1183
     ((setq do-layout t)
      (outline-infer-body-reindent))
1184
     )					; cond
1185 1186 1187 1188 1189 1190 1191 1192 1193 1194

    (if (and do-layout
	     outline-auto-activation
	     (listp outline-layout)
	     (and (not (eq outline-auto-activation 'activate))
		  (if (eq outline-auto-activation 'ask)
		      (if (y-or-n-p (format "Expose %s with layout '%s'? "
					    (buffer-name)
					    outline-layout))
			  t
1195
			(message "Skipped %s layout." (buffer-name))
1196 1197 1198 1199 1200
			nil)
		    t)))
	(save-excursion
	  (message "Adjusting '%s' exposure..." (buffer-name))
	  (goto-char 0)
1201 1202 1203 1204 1205 1206 1207 1208 1209
	  (outline-this-or-next-heading)
	  (condition-case err
	      (progn 
		(apply 'outline-expose-topic (list outline-layout))
		(message "Adjusting '%s' exposure... done." (buffer-name)))
	    ;; Problem applying exposure - notify user, but don't
	    ;; interrupt, eg, file visit:
	    (error (message "%s" (car (cdr err)))
		   (sit-for 1)))))
1210 1211
    outline-mode
    )					; let*
1212
  )  					; defun