allout.el 284 KB
Newer Older
1
;;; allout.el --- extensive outline mode for use alone and with other modes
2

3
;; Copyright (C) 1992, 1993, 1994, 2001, 2002, 2003, 2004, 2005, 2006,
4
;;   2007, 2008, 2009, 2010, 2011  Free Software Foundation, Inc.
Richard M. Stallman's avatar
Richard M. Stallman committed
5

6 7
;; Author: Ken Manheimer <ken dot manheimer at gmail dot com>
;; Maintainer: Ken Manheimer <ken dot manheimer at gmail dot com>
Richard M. Stallman's avatar
Richard M. Stallman committed
8
;; Created: Dec 1991 -- first release to usenet
9
;; Version: 2.3
10
;; Keywords: outlines wp languages
11
;; Website: http://myriadicity.net/Sundry/EmacsAllout
Richard M. Stallman's avatar
Richard M. Stallman committed
12 13 14

;; This file is part of GNU Emacs.

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

Richard M. Stallman's avatar
Richard M. Stallman committed
20
;; GNU Emacs is distributed in the hope that it will be useful,
21 22 23 24 25
;; 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
26
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
Richard M. Stallman's avatar
Richard M. Stallman committed
27

28
;;; Commentary:
29

30 31
;; Allout outline minor mode provides extensive outline formatting and
;; and manipulation beyond standard emacs outline mode.  Some features:
32
;;
33 34 35 36
;;  - Classic outline-mode topic-oriented navigation and exposure adjustment
;;  - Topic-oriented editing including coherent topic and subtopic
;;    creation, promotion, demotion, cut/paste across depths, etc.
;;  - Incremental search with dynamic exposure and reconcealment of text
Richard M. Stallman's avatar
Richard M. Stallman committed
37
;;  - Customizable bullet format -- enables programming-language specific
38
;;    outlining, for code-folding editing.  (Allout code itself is to try it;
Richard M. Stallman's avatar
Richard M. Stallman committed
39
;;    formatted as an outline -- do ESC-x eval-buffer in allout.el; but
40
;;    emacs local file variables need to be enabled when the
Richard M. Stallman's avatar
Richard M. Stallman committed
41
;;    file was visited -- see `enable-local-variables'.)
42 43
;;  - Configurable per-file initial exposure settings
;;  - Symmetric-key and key-pair topic encryption, plus symmetric passphrase
44 45
;;    mnemonic support, with verification against an established passphrase
;;    (using a stashed encrypted dummy string) and user-supplied hint
46 47
;;    maintenance.  Encryption is via the Emacs 'epg' library.  See
;;    allout-toggle-current-subtree-encryption docstring.
48 49
;;  - Automatic topic-number maintenance
;;  - "Hot-spot" operation, for single-keystroke maneuvering and
50
;;    exposure control (see the allout-mode docstring)
51
;;  - Easy rendering of exposed portions into numbered, latex, indented, etc
52
;;    outline styles
Richard M. Stallman's avatar
Richard M. Stallman committed
53
;;  - Careful attention to whitespace -- enabling blank lines between items
54 55 56
;;    and maintenance of hanging indentation (in paragraph auto-fill and
;;    across topic promotion and demotion) of topic bodies consistent with
;;    indentation of their topic header.
57
;;
58
;; and more.
59
;;
60
;; See the `allout-mode' function's docstring for an introduction to the
61 62 63
;; mode.
;;
;; The latest development version and helpful notes are available at
64 65
;; http://myriadicity.net/Sundry/EmacsAllout .
;;
Dave Love's avatar
Dave Love committed
66
;; The outline menubar additions provide quick reference to many of
67
;; the features, and see the docstring of the variable `allout-init'
68
;; for instructions on priming your Emacs session for automatic
69
;; activation of allout-mode.
70
;;
71 72
;; See the docstring of the variables `allout-layout' and
;; `allout-auto-activation' for details on automatic activation of
73
;; `allout-mode' as a minor mode.  (It has changed since allout
74
;; 3.x, for those of you that depend on the old method.)
75
;;
Richard M. Stallman's avatar
Richard M. Stallman committed
76
;; Note -- the lines beginning with `;;;_' are outline topic headers.
Thien-Thi Nguyen's avatar
Thien-Thi Nguyen committed
77
;;        Just `ESC-x eval-buffer' to give it a whirl.
78

79
;; ken manheimer (ken dot manheimer at gmail dot com)
80

81 82
;;; Code:

83
;;;_* Dependency autoloads
84
(require 'overlay)
85
(eval-when-compile
86 87
  ;; Most of the requires here are for stuff covered by autoloads, which
  ;; byte-compiling doesn't trigger.
88
  (require 'epg)
89
  (require 'epa)
90 91 92 93 94 95
  (require 'overlay)
  ;; `cl' is required for `assert'.  `assert' is not covered by a standard
  ;; autoload, but it is a macro, so that eval-when-compile is sufficient
  ;; to byte-compile it in, or to do the require when the buffer evalled.
  (require 'cl)
  )
96

97
;;;_* USER CUSTOMIZATION VARIABLES:
98

99
;;;_ > defgroup allout, allout-keybindings
Stephen Eglen's avatar
Stephen Eglen committed
100 101
(defgroup allout nil
  "Extensive outline mode for use alone and with other modes."
102
  :prefix "allout-"
103
  :group 'outlines)
104 105 106
(defgroup allout-keybindings nil
  "Allout outline mode keyboard bindings configuration."
  :group 'allout)
107 108 109

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

110 111 112
(defvar allout-command-prefix)          ; defined below
(defvar allout-mode-map)

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
;;;_  > allout-keybindings incidentals:
;;;_   > allout-bind-keys &optional varname value
(defun allout-bind-keys (&optional varname value)
  "Rebuild the `allout-mode-map' according to the keybinding specs.

Useful standalone, to init the map, or in customizing the
respective allout-mode keybinding variables, `allout-command-prefix',
`allout-prefixed-keybindings', and `allout-unprefixed-keybindings'"
  ;; Set the customization variable, if any:
  (when varname
    (set-default varname value))
  (let ((map (make-sparse-keymap))
        key)
    (when (boundp 'allout-prefixed-keybindings)
      ;; Be tolerant of the moments when the variables are first being defined.
      (dolist (entry allout-prefixed-keybindings)
        (define-key map
          ;; XXX vector vs non-vector key descriptions?
          (vconcat allout-command-prefix
                   (car (read-from-string (car entry))))
          (cadr entry))))
    (when (boundp 'allout-unprefixed-keybindings)
      (dolist (entry allout-unprefixed-keybindings)
        (define-key map (car (read-from-string (car entry))) (cadr entry))))
    (setq allout-mode-map map)
    map
    ))
;;;_   = allout-command-prefix
141
(defcustom allout-command-prefix "\C-c "
Lute Kamstra's avatar
Lute Kamstra committed
142
  "Key sequence to be used as prefix for outline mode command key bindings.
143 144 145 146

Default is '\C-c<space>'; just '\C-c' is more short-and-sweet, if you're
willing to let allout use a bunch of \C-c keybindings."
  :type 'string
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 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 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
  :group 'allout-keybindings
  :set 'allout-bind-keys)
;;;_   = allout-keybindings-binding
(define-widget 'allout-keybindings-binding 'lazy
  "Structure of allout keybindings customization items."
  :type '(repeat
          (list (string :tag "Key" :value "[(meta control shift ?f)]")
                (function :tag "Function name"
                          :value allout-forward-current-level))))
;;;_   = allout-prefixed-keybindings
(defcustom allout-prefixed-keybindings
  '(("[(control ?n)]" allout-next-visible-heading)
    ("[(control ?p)]" allout-previous-visible-heading)
;;    ("[(control ?u)]" allout-up-current-level)
    ("[(control ?f)]" allout-forward-current-level)
    ("[(control ?b)]" allout-backward-current-level)
    ("[(control ?a)]" allout-beginning-of-current-entry)
    ("[(control ?e)]" allout-end-of-entry)
    ("[(control ?i)]" allout-show-children)
    ("[(control ?i)]" allout-show-children)
    ("[(control ?s)]" allout-show-current-subtree)
    ("[(control ?t)]" allout-toggle-current-subtree-exposure)
    ("[(control ?h)]" allout-hide-current-subtree)
    ("[?h]" allout-hide-current-subtree)
    ("[(control ?o)]" allout-show-current-entry)
    ("[?!]" allout-show-all)
    ("[?x]" allout-toggle-current-subtree-encryption)
    ("[? ]" allout-open-sibtopic)
    ("[?.]" allout-open-subtopic)
    ("[?,]" allout-open-supertopic)
    ("[?']" allout-shift-in)
    ("[?>]" allout-shift-in)
    ("[?<]" allout-shift-out)
    ("[(control ?m)]" allout-rebullet-topic)
    ("[?*]" allout-rebullet-current-heading)
    ("[?']" allout-number-siblings)
    ("[(control ?k)]" allout-kill-topic)
    ("[??]" allout-copy-topic-as-kill)
    ("[?@]" allout-resolve-xref)
    ("[?=?c]" allout-copy-exposed-to-buffer)
    ("[?=?i]" allout-indented-exposed-to-buffer)
    ("[?=?t]" allout-latexify-exposed)
    ("[?=?p]" allout-flatten-exposed-to-buffer)
    )
  "Allout-mode key bindings that are prefixed with `allout-command-prefix'.

See `allout-unprefixed-keybindings' for the list of keybindings
that are not prefixed.

Use vector format for the keys:
  - put literal keys after a '?' question mark, eg: '?a', '?.'
  - enclose control, shift, or meta-modified keys as sequences within
    parentheses, with the literal key, as above, preceded by the name(s)
    of the modifers, eg: [(control ?a)]
See the existing keys for examples.

Functions can be bound to multiple keys, but binding keys to
multiple functions will not work - the last binding for a key
prevails."
  :type 'allout-keybindings-binding
  :group 'allout-keybindings
  :set 'allout-bind-keys
 )
;;;_   = allout-unprefixed-keybindings
(defcustom allout-unprefixed-keybindings
  '(("[(control ?k)]" allout-kill-line)
    ("[??(meta ?k)]" allout-copy-line-as-kill)
    ("[(control ?y)]" allout-yank)
    ("[??(meta ?y)]" allout-yank-pop)
    )
  "Allout-mode functions bound to keys without any added prefix.

This is in contrast to the majority of allout-mode bindings on
`allout-prefixed-bindings', whose bindings are created with a
preceeding command key.

Use vector format for the keys:
  - put literal keys after a '?' question mark, eg: '?a', '?.'
  - enclose control, shift, or meta-modified keys as sequences within
    parentheses, with the literal key, as above, preceded by the name(s)
    of the modifers, eg: [(control ?a)]
See the existing keys for examples."
  :type 'allout-keybindings-binding
  :group 'allout-keybindings
  :set 'allout-bind-keys
  )

;;;_  = allout-preempt-trailing-ctrl-h
(defcustom allout-preempt-trailing-ctrl-h nil
  "Use <prefix>-\C-h, instead of leaving it for describe-prefix-bindings?"
  :type 'boolean
238
  :group 'allout)
Miles Bader's avatar
Miles Bader committed
239

240
;;;_  = allout-keybindings-list
241
;;; You have to reactivate allout-mode to change this var's current setting.
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
(defvar allout-keybindings-list ()
  "*List of `allout-mode' key / function bindings, for `allout-mode-map'.
String or vector key will be prefaced with `allout-command-prefix',
unless optional third, non-nil element is present.")
(setq allout-keybindings-list
      '(
                                        ; Motion commands:
        ("\C-n" allout-next-visible-heading)
        ("\C-p" allout-previous-visible-heading)
        ("\C-u" allout-up-current-level)
        ("\C-f" allout-forward-current-level)
        ("\C-b" allout-backward-current-level)
        ("\C-a" allout-beginning-of-current-entry)
        ("\C-e" allout-end-of-entry)
                                        ; Exposure commands:
257 258
        ([(control i)] allout-show-children) ; xemacs translates "\C-i" to tab
        ("\C-i" allout-show-children)   ; but we still need this for hotspot
259
        ("\C-s" allout-show-current-subtree)
260 261 262 263
        ;; binding to \C-h is included if allout-preempt-trailing-ctrl-h,
        ;; so user controls whether or not to preempt the conventional ^H
        ;; binding to help-command.
        ("\C-h" allout-hide-current-subtree)
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
        ("\C-t" allout-toggle-current-subtree-exposure)
        ("h" allout-hide-current-subtree)
        ("\C-o" allout-show-current-entry)
        ("!" allout-show-all)
        ("x" allout-toggle-current-subtree-encryption)
                                        ; Alteration commands:
        (" " allout-open-sibtopic)
        ("." allout-open-subtopic)
        ("," allout-open-supertopic)
        ("'" allout-shift-in)
        (">" allout-shift-in)
        ("<" allout-shift-out)
        ("\C-m" allout-rebullet-topic)
        ("*" allout-rebullet-current-heading)
        ("#" allout-number-siblings)
        ("\C-k" allout-kill-line t)
280
        ([?\M-k] allout-copy-line-as-kill t)
281
        ("\C-y" allout-yank t)
282
        ([?\M-y] allout-yank-pop t)
283
        ("\C-k" allout-kill-topic)
284
        ([?\M-k] allout-copy-topic-as-kill)
285 286 287 288 289 290 291 292
                                        ; Miscellaneous commands:
	;([?\C-\ ] allout-mark-topic)
        ("@" allout-resolve-xref)
        ("=c" allout-copy-exposed-to-buffer)
        ("=i" allout-indented-exposed-to-buffer)
	("=t" allout-latexify-exposed)
	("=p" allout-flatten-exposed-to-buffer)))

293 294
;;;_  = allout-auto-activation
(defcustom allout-auto-activation nil
Lute Kamstra's avatar
Lute Kamstra committed
295
  "Regulates auto-activation modality of allout outlines -- see `allout-init'.
296

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

302
With value t, auto-mode-activation and auto-layout are enabled.
303
\(This also depends on `allout-find-file-hook' being installed in
304
`find-file-hook', which is also done by `allout-init'.)
305 306 307 308

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

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

312
With value nil, neither auto-mode-activation nor auto-layout are
313 314
enabled.

315
See the docstring for `allout-init' for the proper interface to
Dave Love's avatar
Dave Love committed
316 317 318 319 320 321
this variable."
  :type '(choice (const :tag "On" t)
                (const :tag "Ask about layout" "ask")
                (const :tag "Mode only" "activate")
                (const :tag "Off" nil))
  :group 'allout)
322 323
;;;_  = allout-default-layout
(defcustom allout-default-layout '(-2 : 0)
Lute Kamstra's avatar
Lute Kamstra committed
324
  "Default allout outline layout specification.
325 326 327 328 329 330 331 332 333 334 335 336

This setting specifies the outline exposure to use when
`allout-layout' has the local value `t'.  This docstring describes the
layout specifications.

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

The types of elements in the layout specification are:

Richard M. Stallman's avatar
Richard M. Stallman committed
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
 INTEGER -- dictate the relative depth to open the corresponding topic(s),
            where:
         -- negative numbers force the topic to be closed before opening
            to the absolute value of the number, so all siblings are open
            only to that level.
         -- positive numbers open to the relative depth indicated by the
            number, but do not force already opened subtopics to be closed.
         -- 0 means to close topic -- hide all subitems.
 :   -- repeat spec -- apply the preceeding element to all siblings at
        current level, *up to* those siblings that would be covered by specs
        following the `:' on the list.  Ie, apply to all topics at level but
        trailing ones accounted for by trailing specs.  (Only the first of
        multiple colons at the same level is honored -- later ones are ignored.)
 *   -- completely exposes the topic, including bodies
 +   -- exposes all subtopics, but not the bodies
 -   -- exposes the body of the corresponding topic, but not subtopics
 LIST -- a nested layout spec, to be applied intricately to its
354
        corresponding item(s)
Richard M. Stallman's avatar
Richard M. Stallman committed
355

356
Examples:
Richard M. Stallman's avatar
Richard M. Stallman committed
357
 (-2 : 0)
358 359
	Collapse the top-level topics to show their children and
        grandchildren, but completely collapse the final top-level topic.
Richard M. Stallman's avatar
Richard M. Stallman committed
360
 (-1 () : 1 0)
361 362 363 364
	Close the first topic so only the immediate subtopics are shown,
        leave the subsequent topics exposed as they are until the second
	second to last topic, which is exposed at least one level, and
        completely close the last topic.
Richard M. Stallman's avatar
Richard M. Stallman committed
365
 (-2 : -1 *)
366 367 368
        Expose children and grandchildren of all topics at current
	level except the last two; expose children of the second to
	last and completely expose the last one, including its subtopics.
369

370
See `allout-expose-topic' for more about the exposure process.
371

372 373
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
374 375 376 377 378 379 380 381 382 383 384 385 386 387
is modulo the setting of `allout-use-mode-specific-leader', which see."
  :type 'allout-layout-type
  :group 'allout)
;;;_  : allout-layout-type
(define-widget 'allout-layout-type 'lazy
  "Allout layout format customization basic building blocks."
  :type '(repeat
          (choice (integer :tag "integer (<= zero is strict)")
                  (const :tag ": (repeat prior)" :)
                  (const :tag "* (completely expose)" *)
                  (const :tag "+ (expose all offspring, headlines only)" +)
                  (const :tag "- (expose topic body but not offspring)" -)
                  (allout-layout-type :tag "<Nested layout>"))))

388 389
;;;_  = allout-inhibit-auto-fill
(defcustom allout-inhibit-auto-fill nil
Lute Kamstra's avatar
Lute Kamstra committed
390
  "If non-nil, auto-fill will be inhibited in the allout buffers.
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405

You can customize this setting to set it for all allout buffers, or set it
in individual buffers if you want to inhibit auto-fill only in particular
buffers.  (You could use a function on `allout-mode-hook' to inhibit
auto-fill according, eg, to the major mode.)

If you don't set this and auto-fill-mode is enabled, allout will use the
value that `normal-auto-fill-function', if any, when allout mode starts, or
else allout's special hanging-indent maintaining auto-fill function,
`allout-auto-fill'."
  :type 'boolean
  :group 'allout)
(make-variable-buffer-local 'allout-inhibit-auto-fill)
;;;_  = allout-use-hanging-indents
(defcustom allout-use-hanging-indents t
Lute Kamstra's avatar
Lute Kamstra committed
406
  "If non-nil, topic body text auto-indent defaults to indent of the header.
407
Ie, it is indented to be just past the header prefix.  This is
Miles Bader's avatar
Miles Bader committed
408
relevant mostly for use with `indented-text-mode', or other situations
409 410 411 412 413 414 415 416 417 418
where auto-fill occurs."
  :type 'boolean
  :group 'allout)
(make-variable-buffer-local 'allout-use-hanging-indents)
;;;###autoload
(put 'allout-use-hanging-indents 'safe-local-variable
     (if (fboundp 'booleanp) 'booleanp '(lambda (x) (member x '(t nil)))))
;;;_  = allout-reindent-bodies
(defcustom allout-reindent-bodies (if allout-use-hanging-indents
				    'text)
Lute Kamstra's avatar
Lute Kamstra committed
419
  "Non-nil enables auto-adjust of topic body hanging indent with depth shifts.
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435

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."
  :type '(choice (const nil) (const t) (const text) (const force))
  :group 'allout)

(make-variable-buffer-local 'allout-reindent-bodies)
;;;###autoload
(put 'allout-reindent-bodies 'safe-local-variable
     '(lambda (x) (memq x '(nil t text force))))

436 437
;;;_  = allout-show-bodies
(defcustom allout-show-bodies nil
Lute Kamstra's avatar
Lute Kamstra committed
438
  "If non-nil, show entire body when exposing a topic, rather than
Dave Love's avatar
Dave Love committed
439 440 441
just the header."
  :type 'boolean
  :group 'allout)
442
(make-variable-buffer-local 'allout-show-bodies)
443 444
;;;###autoload
(put 'allout-show-bodies 'safe-local-variable
445
     (if (fboundp 'booleanp) 'booleanp '(lambda (x) (member x '(t nil)))))
Richard M. Stallman's avatar
Richard M. Stallman committed
446

447 448
;;;_  = allout-beginning-of-line-cycles
(defcustom allout-beginning-of-line-cycles t
Lute Kamstra's avatar
Lute Kamstra committed
449
  "If non-nil, \\[allout-beginning-of-line] will cycle through smart-placement options.
450 451 452 453 454 455 456 457 458 459 460 461 462 463

Cycling only happens on when the command is repeated, not when it
follows a different command.

Smart-placement means that repeated calls to this function will
advance as follows:

 - if the cursor is on a non-headline body line and not on the first column:
   then it goes to the first column
 - if the cursor is on the first column of a non-headline body line:
   then it goes to the start of the headline within the item body
 - if the cursor is on the headline and not the start of the headline:
   then it goes to the start of the headline
 - if the cursor is on the start of the headline:
464
   then it goes to the bullet character (for hotspot navigation)
465
 - if the cursor is on the bullet character:
466
   then it goes to the first column of that line (the headline)
467 468 469 470 471 472 473 474 475 476 477 478 479
 - if the cursor is on the first column of the headline:
   then it goes to the start of the headline within the item body.

In this fashion, you can use the beginning-of-line command to do
its normal job and then, when repeated, advance through the
entry, cycling back to start.

If this configuration variable is nil, then the cursor is just
advanced to the beginning of the line and remains there on
repeated calls."
  :type 'boolean :group 'allout)
;;;_  = allout-end-of-line-cycles
(defcustom allout-end-of-line-cycles t
Lute Kamstra's avatar
Lute Kamstra committed
480
  "If non-nil, \\[allout-end-of-line] will cycle through smart-placement options.
481 482 483 484

Cycling only happens on when the command is repeated, not when it
follows a different command.

Richard M. Stallman's avatar
Richard M. Stallman committed
485
Smart placement means that repeated calls to this function will
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
advance as follows:

 - if the cursor is not on the end-of-line,
   then it goes to the end-of-line
 - if the cursor is on the end-of-line but not the end-of-entry,
   then it goes to the end-of-entry, exposing it if necessary
 - if the cursor is on the end-of-entry,
   then it goes to the end of the head line

In this fashion, you can use the end-of-line command to do its
normal job and then, when repeated, advance through the entry,
cycling back to start.

If this configuration variable is nil, then the cursor is just
advanced to the end of the line and remains there on repeated
calls."
  :type 'boolean :group 'allout)

504 505
;;;_  = allout-header-prefix
(defcustom allout-header-prefix "."
506 507
;; this string is treated as literal match.  it will be `regexp-quote'd, so
;; one cannot use regular expressions to match varying header prefixes.
Lute Kamstra's avatar
Lute Kamstra committed
508
  "Leading string which helps distinguish topic headers.
509 510

Outline topic header lines are identified by a leading topic
511
header prefix, which mostly have the value of this var at their front.
512 513
Level 1 topics are exceptions.  They consist of only a single
character, which is typically set to the `allout-primary-bullet'."
Stephen Eglen's avatar
Stephen Eglen committed
514 515
  :type 'string
  :group 'allout)
516
(make-variable-buffer-local 'allout-header-prefix)
517 518
;;;###autoload
(put 'allout-header-prefix 'safe-local-variable 'stringp)
519 520
;;;_  = allout-primary-bullet
(defcustom allout-primary-bullet "*"
521 522 523
  "Bullet used for top-level outline topics.

Outline topic header lines are identified by a leading topic header
524
prefix, which is concluded by bullets that includes the value of this
525
var and the respective allout-*-bullets-string vars.
526

527
The value of an asterisk (`*') provides for backwards compatibility
528
with the original Emacs outline mode.  See `allout-plain-bullets-string'
529
and `allout-distinctive-bullets-string' for the range of available
Stephen Eglen's avatar
Stephen Eglen committed
530 531 532
bullets."
  :type 'string
  :group 'allout)
533
(make-variable-buffer-local 'allout-primary-bullet)
534 535
;;;###autoload
(put 'allout-primary-bullet 'safe-local-variable 'stringp)
536
;;;_  = allout-plain-bullets-string
537
(defcustom allout-plain-bullets-string ".,"
Lute Kamstra's avatar
Lute Kamstra committed
538
  "The bullets normally used in outline topic prefixes.
539

540
See `allout-distinctive-bullets-string' for the other kind of
541
bullets.
Richard M. Stallman's avatar
Richard M. Stallman committed
542

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

545
Outline mode has to be reactivated in order for changes to the value
Stephen Eglen's avatar
Stephen Eglen committed
546 547 548
of this var to take effect."
  :type 'string
  :group 'allout)
549
(make-variable-buffer-local 'allout-plain-bullets-string)
550 551
;;;###autoload
(put 'allout-plain-bullets-string 'safe-local-variable 'stringp)
552
;;;_  = allout-distinctive-bullets-string
553
(defcustom allout-distinctive-bullets-string "*+-=>()[{}&!?#%\"X@$~_\\:;^"
Lute Kamstra's avatar
Lute Kamstra committed
554
  "Persistent outline header bullets used to distinguish special topics.
Richard M. Stallman's avatar
Richard M. Stallman committed
555

556 557 558 559 560 561 562 563 564 565 566
These bullets are distinguish topics with particular character.
They are not used by default in the topic creation routines, but
are offered as options when you modify topic creation with a
universal argument \(\\[universal-argument]), or during rebulleting \(\\[allout-rebullet-current-heading]).

Distinctive bullets are not cycled when topics are shifted or
otherwise automatically rebulleted, so their marking is
persistent until deliberately changed.  Their significance is
purely by convention, however.  Some conventions suggest
themselves:

Richard M. Stallman's avatar
Richard M. Stallman committed
567 568 569 570 571
 `(' - open paren -- an aside or incidental point
 `?' - question mark -- uncertain or outright question
 `!' - exclamation point/bang -- emphatic
 `[' - open square bracket -- meta-note, about item instead of item's subject
 `\"' - double quote -- a quotation or other citation
572
 `=' - equal sign -- an assignment, some kind of definition
Richard M. Stallman's avatar
Richard M. Stallman committed
573
 `^' - carat -- relates to something above
574 575 576

Some are more elusive, but their rationale may be recognizable:

Richard M. Stallman's avatar
Richard M. Stallman committed
577 578 579
 `+' - plus -- pending consideration, completion
 `_' - underscore -- done, completed
 `&' - ampersand -- addendum, furthermore
580 581 582 583

\(Some other non-plain bullets have special meaning to the
software.  By default:

Richard M. Stallman's avatar
Richard M. Stallman committed
584 585
 `~' marks encryptable topics -- see `allout-topic-encryption-bullet'
 `#' marks auto-numbered bullets -- see `allout-numbered-bullet'.)
586 587 588

See `allout-plain-bullets-string' for the standard, alternating
bullets.
Richard M. Stallman's avatar
Richard M. Stallman committed
589

590
You must run `set-allout-regexp' in order for outline mode to
591
adopt changes of this value.
592

593
DO NOT include the close-square-bracket, `]', on either of the bullet
Stephen Eglen's avatar
Stephen Eglen committed
594 595 596
strings."
  :type 'string
  :group 'allout)
597
(make-variable-buffer-local 'allout-distinctive-bullets-string)
598 599
;;;###autoload
(put 'allout-distinctive-bullets-string 'safe-local-variable 'stringp)
Richard M. Stallman's avatar
Richard M. Stallman committed
600

601 602
;;;_  = allout-use-mode-specific-leader
(defcustom allout-use-mode-specific-leader t
Lute Kamstra's avatar
Lute Kamstra committed
603
  "When non-nil, use mode-specific topic-header prefixes.
604

605 606 607 608
Allout outline mode will use the mode-specific `allout-mode-leaders' or
comment-start string, if any, to lead the topic prefix string, so topic
headers look like comments in the programming language.  It will also use
the comment-start string, with an '_' appended, for `allout-primary-bullet'.
609

610 611
String values are used as literals, not regular expressions, so
do not escape any regulare-expression characters.
612

613
Value t means to first check for assoc value in `allout-mode-leaders'
614
alist, then use comment-start string, if any, then use default (`.').
Dave Love's avatar
Dave Love committed
615
\(See note about use of comment-start strings, below.)
616

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

620
Value nil means to always use the default (`.') and leave
621 622 623 624 625 626
`allout-primary-bullet' unaltered.

comment-start strings that do not end in spaces are tripled in
the header-prefix, 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
627
is substituted for the space.  [This presumes that the space is
628 629 630
for appearance, not comment syntax.  You can use
`allout-mode-leaders' to override this behavior, when
undesired.]"
631
  :type '(choice (const t) (const nil) string
632
		 (const allout-mode-leaders)
Stephen Eglen's avatar
Stephen Eglen committed
633 634
		 (const comment-start))
  :group 'allout)
635 636
;;;###autoload
(put 'allout-use-mode-specific-leader 'safe-local-variable
637 638
     '(lambda (x) (or (memq x '(t nil allout-mode-leaders comment-start))
                      (stringp x))))
639 640 641
;;;_  = allout-mode-leaders
(defvar allout-mode-leaders '()
  "Specific allout-prefix leading strings per major modes.
642

643 644 645
Use this if the mode's comment-start string isn't what you
prefer, or if the mode lacks a comment-start string.  See
`allout-use-mode-specific-leader' for more details.
646 647 648 649

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
650
from regular comments that start at the beginning-of-line.")
651

652 653
;;;_  = allout-old-style-prefixes
(defcustom allout-old-style-prefixes nil
Lute Kamstra's avatar
Lute Kamstra committed
654
  "When non-nil, use only old-and-crusty `outline-mode' `*' topic prefixes.
655 656

Non-nil restricts the topic creation and modification
657
functions to asterix-padded prefixes, so they look exactly
658
like the original Emacs-outline style prefixes.
Richard M. Stallman's avatar
Richard M. Stallman committed
659

660
Whatever the setting of this variable, both old and new style prefixes
Stephen Eglen's avatar
Stephen Eglen committed
661 662 663
are always respected by the topic maneuvering functions."
  :type 'boolean
  :group 'allout)
664
(make-variable-buffer-local 'allout-old-style-prefixes)
665 666
;;;###autoload
(put 'allout-old-style-prefixes 'safe-local-variable
667
     (if (fboundp 'booleanp) 'booleanp '(lambda (x) (member x '(t nil)))))
Richard M. Stallman's avatar
Richard M. Stallman committed
668
;;;_  = allout-stylish-prefixes -- alternating bullets
669
(defcustom allout-stylish-prefixes t
Lute Kamstra's avatar
Lute Kamstra committed
670
  "Do fancy stuff with topic prefix bullets according to level, etc.
671

672 673 674
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.
675
Otherwise, only asterisks (`*') and distinctive bullets are used.
676 677 678

This is how an outline can look (but sans indentation) with stylish
prefixes:
679 680 681 682 683

    * Top level
    .* A topic
    . + One level 3 subtopic
    .  . One level 4 subtopic
684
    .  . A second 4 subtopic
685
    . + Another level 3 subtopic
686 687 688 689
    .  #1 A numbered level 4 subtopic
    .  #2 Another
    .  ! Another level 4 subtopic with a different distinctive bullet
    .  #4 And another numbered level 4 subtopic
690

691 692
This would be an outline with stylish prefixes inhibited (but the
numbered and other distinctive bullets retained):
693 694 695

    * Top level
    .* A topic
696 697 698 699 700 701 702 703
    . * 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
704 705 706 707 708

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

709
The setting of this var is not relevant when `allout-old-style-prefixes'
Stephen Eglen's avatar
Stephen Eglen committed
710 711 712
is non-nil."
  :type 'boolean
  :group 'allout)
713
(make-variable-buffer-local 'allout-stylish-prefixes)
714 715
;;;###autoload
(put 'allout-stylish-prefixes 'safe-local-variable
716
     (if (fboundp 'booleanp) 'booleanp '(lambda (x) (member x '(t nil)))))
Richard M. Stallman's avatar
Richard M. Stallman committed
717

718 719
;;;_  = allout-numbered-bullet
(defcustom allout-numbered-bullet "#"
Lute Kamstra's avatar
Lute Kamstra committed
720
  "String designating bullet of topics that have auto-numbering; nil for none.
721

722
Topics having this bullet have automatic maintenance of a sibling
723
sequence-number tacked on, just after the bullet.  Conventionally set
724
to \"#\", you can set it to a bullet of your choice.  A nil value
Stephen Eglen's avatar
Stephen Eglen committed
725 726 727
disables numbering maintenance."
  :type '(choice (const nil) string)
  :group 'allout)
728
(make-variable-buffer-local 'allout-numbered-bullet)
729
;;;###autoload
730 731 732 733
(put 'allout-numbered-bullet 'safe-local-variable
     (if (fboundp 'string-or-null-p)
         'string-or-null-p
       '(lambda (x) (or (stringp x) (null x)))))
734 735
;;;_  = allout-file-xref-bullet
(defcustom allout-file-xref-bullet "@"
Lute Kamstra's avatar
Lute Kamstra committed
736
  "Bullet signifying file cross-references, for `allout-resolve-xref'.
737

Dave Love's avatar
Dave Love committed
738
Set this var to the bullet you want to use for file cross-references."
Stephen Eglen's avatar
Stephen Eglen committed
739 740
  :type '(choice (const nil) string)
  :group 'allout)
741
;;;###autoload
742 743 744 745
(put 'allout-file-xref-bullet 'safe-local-variable
     (if (fboundp 'string-or-null-p)
         'string-or-null-p
       '(lambda (x) (or (stringp x) (null x)))))
746 747
;;;_  = allout-presentation-padding
(defcustom allout-presentation-padding 2
Lute Kamstra's avatar
Lute Kamstra committed
748
  "Presentation-format white-space padding factor, for greater indent."
Dave Love's avatar
Dave Love committed
749 750 751
  :type 'integer
  :group 'allout)

752
(make-variable-buffer-local 'allout-presentation-padding)
753 754
;;;###autoload
(put 'allout-presentation-padding 'safe-local-variable 'integerp)
Dave Love's avatar
Dave Love committed
755

756 757
;;;_  = allout-abbreviate-flattened-numbering
(defcustom allout-abbreviate-flattened-numbering nil
Lute Kamstra's avatar
Lute Kamstra committed
758
  "If non-nil, `allout-flatten-exposed-to-buffer' abbreviates topic
Dave Love's avatar
Dave Love committed
759 760 761 762 763
numbers to minimal amount with some context.  Otherwise, entire
numbers are always used."
  :type 'boolean
  :group 'allout)

764
;;;_ + LaTeX formatting
765 766
;;;_  - allout-number-pages
(defcustom allout-number-pages nil
Lute Kamstra's avatar
Lute Kamstra committed
767
  "Non-nil turns on page numbering for LaTeX formatting of an outline."
Stephen Eglen's avatar
Stephen Eglen committed
768 769
  :type 'boolean
  :group 'allout)
770 771
;;;_  - allout-label-style
(defcustom allout-label-style "\\large\\bf"
Lute Kamstra's avatar
Lute Kamstra committed
772
  "Font and size of labels for LaTeX formatting of an outline."
Stephen Eglen's avatar
Stephen Eglen committed
773 774
  :type 'string
  :group 'allout)
775 776
;;;_  - allout-head-line-style
(defcustom allout-head-line-style "\\large\\sl "
Lute Kamstra's avatar
Lute Kamstra committed
777
  "Font and size of entries for LaTeX formatting of an outline."
Stephen Eglen's avatar
Stephen Eglen committed
778 779
  :type 'string
  :group 'allout)
780 781
;;;_  - allout-body-line-style
(defcustom allout-body-line-style " "
Lute Kamstra's avatar
Lute Kamstra committed
782
  "Font and size of entries for LaTeX formatting of an outline."
Stephen Eglen's avatar
Stephen Eglen committed
783 784
  :type 'string
  :group 'allout)
785 786
;;;_  - allout-title-style
(defcustom allout-title-style "\\Large\\bf"
Lute Kamstra's avatar
Lute Kamstra committed
787
  "Font and size of titles for LaTeX formatting of an outline."
Stephen Eglen's avatar
Stephen Eglen committed
788 789
  :type 'string
  :group 'allout)
790
;;;_  - allout-title
791
(defcustom allout-title '(or buffer-file-name (buffer-name))
Lute Kamstra's avatar
Lute Kamstra committed
792
  "Expression to be evaluated to determine the title for LaTeX
Stephen Eglen's avatar
Stephen Eglen committed
793 794 795
formatted copy."
  :type 'sexp
  :group 'allout)
796 797
;;;_  - allout-line-skip
(defcustom allout-line-skip ".05cm"
Lute Kamstra's avatar
Lute Kamstra committed
798
  "Space between lines for LaTeX formatting of an outline."
Stephen Eglen's avatar
Stephen Eglen committed
799 800
  :type 'string
  :group 'allout)
801 802
;;;_  - allout-indent
(defcustom allout-indent ".3cm"
Lute Kamstra's avatar
Lute Kamstra committed
803
  "LaTeX formatted depth-indent spacing."
Stephen Eglen's avatar
Stephen Eglen committed
804 805
  :type 'string
  :group 'allout)
806

807
;;;_ + Topic encryption
808 809 810 811
;;;_  = allout-encryption group
(defgroup allout-encryption nil
  "Settings for topic encryption features of allout outliner."
  :group 'allout)
812 813
;;;_  = allout-topic-encryption-bullet
(defcustom allout-topic-encryption-bullet "~"
Lute Kamstra's avatar
Lute Kamstra committed
814
  "Bullet signifying encryption of the entry's body."
815
  :type '(choice (const nil) string)
816
  :version "22.1"
817
  :group 'allout-encryption)
818
;;;_  = allout-encrypt-unencrypted-on-saves
819
(defcustom allout-encrypt-unencrypted-on-saves t
Lute Kamstra's avatar
Lute Kamstra committed
820
  "When saving, should topics pending encryption be encrypted?
821 822 823 824 825

The idea is to prevent file-system exposure of any un-encrypted stuff, and
mostly covers both deliberate file writes and auto-saves.

 - Yes: encrypt all topics pending encryption, even if it's the one
826
        currently being edited.  (In that case, the currently edited topic
827 828 829 830
        will be automatically decrypted before any user interaction, so they
        can continue editing but the copy on the file system will be
        encrypted.)
        Auto-saves will use the \"All except current topic\" mode if this
Richard M. Stallman's avatar
Richard M. Stallman committed
831
        one is selected, to avoid practical difficulties -- see below.
832 833 834
 - All except current topic: skip the topic currently being edited, even if
       it's pending encryption.  This may expose the current topic on the
       file sytem, but avoids the nuisance of prompts for the encryption
835
       passphrase in the middle of editing for, eg, autosaves.
836 837 838 839
       This mode is used for auto-saves for both this option and \"Yes\".
 - No: leave it to the user to encrypt any unencrypted topics.

For practical reasons, auto-saves always use the 'except-current policy
840
when auto-encryption is enabled.  (Otherwise, spurious passphrase prompts
841 842
and unavoidable timing collisions are too disruptive.)  If security for a
file requires that even the current topic is never auto-saved in the clear,
843 844 845 846 847
disable auto-saves for that file."

  :type '(choice (const :tag "Yes" t)
                 (const :tag "All except current topic" except-current)
                 (const :tag "No" nil))
848
  :version "22.1"
849
  :group 'allout-encryption)
850 851
(make-variable-buffer-local 'allout-encrypt-unencrypted-on-saves)

852 853 854
;;;_ + Developer
;;;_  = allout-developer group
(defgroup allout-developer nil
855
  "Allout settings developers care about, including topic encryption and more."
856 857 858
  :group 'allout)
;;;_  = allout-run-unit-tests-on-load
(defcustom allout-run-unit-tests-on-load nil
Lute Kamstra's avatar
Lute Kamstra committed
859
  "When non-nil, unit tests will be run at end of loading the allout module.
860 861 862 863

Generally, allout code developers are the only ones who'll want to set this.

\(If set, this makes it an even better practice to exercise changes by
864 865
doing byte-compilation with a repeat count, so the file is loaded after
compilation.)
866 867 868 869 870

See `allout-run-unit-tests' to see what's run."
  :type 'boolean
  :group 'allout-developer)

871 872
;;;_ + Miscellaneous customization

873 874
;;;_  = allout-enable-file-variable-adjustment
(defcustom allout-enable-file-variable-adjustment t
Lute Kamstra's avatar
Lute Kamstra committed
875
  "If non-nil, some allout outline actions edit Emacs local file var text.
876 877 878

This can range from changes to existing entries, addition of new ones,
and creation of a new local variables section when necessary.
879

880 881
Emacs file variables adjustments are also inhibited if `enable-local-variables'
is nil.
882

883
Operations potentially causing edits include allout encryption routines.
884
For details, see `allout-toggle-current-subtree-encryption's docstring."
Stephen Eglen's avatar
Stephen Eglen committed
885 886
  :type 'boolean
  :group 'allout)
887
(make-variable-buffer-local 'allout-enable-file-variable-adjustment)
888

Richard M. Stallman's avatar
Richard M. Stallman committed
889
;;;_* CODE -- no user customizations below.
890

Dave Love's avatar
Dave Love committed
891 892
;;;_ #1 Internal Outline Formatting and Configuration
;;;_  : Version
893
;;;_   = allout-version
894
(defvar allout-version "2.3"
895
  "Version of currently loaded outline package.  (allout.el)")
896 897
;;;_   > allout-version
(defun allout-version (&optional here)
898 899
  "Return string describing the loaded outline version."
  (interactive "P")
900
  (let ((msg (concat "Allout Outline Mode v " allout-version)))
901
    (if here (insert msg))
902 903
    (message "%s" msg)
    msg))
904 905 906 907
;;;_  : Mode activation (defined here because it's referenced early)
;;;_   = allout-mode
(defvar allout-mode nil "Allout outline mode minor-mode flag.")
(make-variable-buffer-local 'allout-mode)
908
;;;_   = allout-layout nil
Richard M. Stallman's avatar
Richard M. Stallman committed
909
(defvar allout-layout nil            ; LEAVE GLOBAL VALUE NIL -- see docstring.
910 911
  "Buffer-specific setting for allout layout.

912
In buffers where this is non-nil (and if `allout-init' has been run, to
913 914 915 916 917 918 919 920 921 922 923
enable this behavior), `allout-mode' will be automatically activated.  The
layout dictated by the value will be used to set the initial exposure when
`allout-mode' is activated.

\*You should not setq-default this variable non-nil unless you want every
visited file to be treated as an allout file.*

The value would typically be set by a file local variable.  For
example, the following lines at the bottom of an Emacs Lisp file:

;;;Local variables:
924
;;;allout-layout: (0 : -1 -1 0)
925 926 927 928
;;;End:

dictate activation of `allout-mode' mode when the file is visited
\(presuming allout-init was already run), followed by the
929
equivalent of `(allout-expose-topic 0 : -1 -1 0)'.  (This is
930 931 932 933 934 935
the layout used for the allout.el source file.)

`allout-default-layout' describes the specification format.
`allout-layout' can additionally have the value `t', in which
case the value of `allout-default-layout' is used.")
(make-variable-buffer-local 'allout-layout)
936
;;;###autoload
937
(put 'allout-layout 'safe-local-variable
938
     '(lambda (x) (or (numberp x) (listp x) (memq x '(: * + -)))))
939

Dave Love's avatar
Dave Love committed
940
;;;_  : Topic header format
941 942
;;;_   = allout-regexp
(defvar allout-regexp ""
943
  "*Regular expression to match the beginning of a heading line.
944

945 946
Any line whose beginning matches this regexp is considered a
heading.  This var is set according to the user configuration vars
947
by `set-allout-regexp'.")
948 949 950
(make-variable-buffer-local 'allout-regexp)
;;;_   = allout-bullets-string
(defvar allout-bullets-string ""
951 952
  "A string dictating the valid set of outline topic bullets.

Richard M. Stallman's avatar
Richard M. Stallman committed
953
This var should *not* be set by the user -- it is set by `set-allout-regexp',
954 955 956 957 958
and is produced from the elements of `allout-plain-bullets-string'
and `allout-distinctive-bullets-string'.")
(make-variable-buffer-local 'allout-bullets-string)
;;;_   = allout-bullets-string-len
(defvar allout-bullets-string-len 0
959
  "Length of current buffers' `allout-plain-bullets-string'.")
960
(make-variable-buffer-local 'allout-bullets-string-len)
961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982
;;;_   = allout-depth-specific-regexp
(defvar allout-depth-specific-regexp ""
  "*Regular expression to match a heading line prefix for a particular depth.

This expression is used to search for depth-specific topic
headers at depth 2 and greater.  Use `allout-depth-one-regexp'
for to seek topics at depth one.

This var is set according to the user configuration vars by
`set-allout-regexp'.  It is prepared with format strings for two
decimal numbers, which should each be one less than the depth of the
topic prefix to be matched.")
(make-variable-buffer-local 'allout-depth-specific-regexp)
;;;_   = allout-depth-one-regexp
(defvar allout-depth-one-regexp ""
  "*Regular expression to match a heading line prefix for depth one.

This var is set according to the user configuration vars by
`set-allout-regexp'.  It is prepared with format strings for two
decimal numbers, which should each be one less than the depth of the
topic prefix to be matched.")
(make-variable-buffer-local 'allout-depth-one-regexp)
983 984
;;;_   = allout-line-boundary-regexp
(defvar allout-line-boundary-regexp ()
985
  "`allout-regexp' prepended with a newline for the search target.
986

987
This is properly set by `set-allout-regexp'.")
988 989 990
(make-variable-buffer-local 'allout-line-boundary-regexp)
;;;_   = allout-bob-regexp
(defvar allout-bob-regexp ()
991
  "Like `allout-line-boundary-regexp', for headers at beginning of buffer.")