* lisp/calendar/holidays.el (calendar-check-holidays): Doc fix.
[bpt/emacs.git] / lisp / allout.el
index 1a7d8cb..4002f12 100644 (file)
@@ -234,7 +234,7 @@ 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)]
+    of the modifiers, eg: [(control ?a)]
 See the existing keys for examples.
 
 Functions can be bound to multiple keys, but binding keys to
@@ -255,13 +255,13 @@ prevails."
 
 This is in contrast to the majority of allout-mode bindings on
 `allout-prefixed-bindings', whose bindings are created with a
-preceeding command key.
+preceding 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)]
+    of the modifiers, eg: [(control ?a)]
 See the existing keys for examples."
   :type 'allout-keybindings-binding
   :group 'allout-keybindings
@@ -310,6 +310,7 @@ Auto-layout is not.
 
 With value nil, inhibit any automatic allout-mode activation."
   :set 'allout-auto-activation-helper
+  ;; FIXME: Using strings here is unusual and less efficient than symbols.
   :type '(choice (const :tag "On" t)
                 (const :tag "Ask about layout" "ask")
                 (const :tag "Mode only" "activate")
@@ -339,7 +340,7 @@ The types of elements in the layout specification are:
          -- 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
+ :   -- repeat spec -- apply the preceding 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
@@ -398,6 +399,12 @@ else allout's special hanging-indent maintaining auto-fill function,
   :type 'boolean
   :group 'allout)
 (make-variable-buffer-local 'allout-inhibit-auto-fill)
+;;;_  = allout-inhibit-auto-fill-on-headline
+(defcustom allout-inhibit-auto-fill-on-headline nil
+  "If non-nil, auto-fill will be inhibited while on topic's header line."
+  :type 'boolean
+  :group 'allout)
+(make-variable-buffer-local 'allout-inhibit-auto-fill-on-headline)
 ;;;_  = allout-use-hanging-indents
 (defcustom allout-use-hanging-indents t
   "If non-nil, topic body text auto-indent defaults to indent of the header.
@@ -409,7 +416,7 @@ where auto-fill occurs."
 (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)))))
+     (if (fboundp 'booleanp) 'booleanp (lambda (x) (member x '(t nil)))))
 ;;;_  = allout-reindent-bodies
 (defcustom allout-reindent-bodies (if allout-use-hanging-indents
                                    'text)
@@ -428,7 +435,7 @@ those that do not have the variable `comment-start' set.  A value of
 (make-variable-buffer-local 'allout-reindent-bodies)
 ;;;###autoload
 (put 'allout-reindent-bodies 'safe-local-variable
-     '(lambda (x) (memq x '(nil t text force))))
+     (lambda (x) (memq x '(nil t text force))))
 
 ;;;_  = allout-show-bodies
 (defcustom allout-show-bodies nil
@@ -439,7 +446,7 @@ just the header."
 (make-variable-buffer-local 'allout-show-bodies)
 ;;;###autoload
 (put 'allout-show-bodies 'safe-local-variable
-     (if (fboundp 'booleanp) 'booleanp '(lambda (x) (member x '(t nil)))))
+     (if (fboundp 'booleanp) 'booleanp (lambda (x) (member x '(t nil)))))
 
 ;;;_  = allout-beginning-of-line-cycles
 (defcustom allout-beginning-of-line-cycles t
@@ -631,7 +638,7 @@ undesired.]"
   :group 'allout)
 ;;;###autoload
 (put 'allout-use-mode-specific-leader 'safe-local-variable
-     '(lambda (x) (or (memq x '(t nil allout-mode-leaders comment-start))
+     (lambda (x) (or (memq x '(t nil allout-mode-leaders comment-start))
                       (stringp x))))
 ;;;_  = allout-mode-leaders
 (defvar allout-mode-leaders '()
@@ -661,7 +668,7 @@ are always respected by the topic maneuvering functions."
 (make-variable-buffer-local 'allout-old-style-prefixes)
 ;;;###autoload
 (put 'allout-old-style-prefixes 'safe-local-variable
-     (if (fboundp 'booleanp) 'booleanp '(lambda (x) (member x '(t nil)))))
+     (if (fboundp 'booleanp) 'booleanp (lambda (x) (member x '(t nil)))))
 ;;;_  = allout-stylish-prefixes -- alternating bullets
 (defcustom allout-stylish-prefixes t
   "Do fancy stuff with topic prefix bullets according to level, etc.
@@ -710,7 +717,7 @@ is non-nil."
 (make-variable-buffer-local 'allout-stylish-prefixes)
 ;;;###autoload
 (put 'allout-stylish-prefixes 'safe-local-variable
-     (if (fboundp 'booleanp) 'booleanp '(lambda (x) (member x '(t nil)))))
+     (if (fboundp 'booleanp) 'booleanp (lambda (x) (member x '(t nil)))))
 
 ;;;_  = allout-numbered-bullet
 (defcustom allout-numbered-bullet "#"
@@ -727,7 +734,7 @@ disables numbering maintenance."
 (put 'allout-numbered-bullet 'safe-local-variable
      (if (fboundp 'string-or-null-p)
          'string-or-null-p
-       '(lambda (x) (or (stringp x) (null x)))))
+       (lambda (x) (or (stringp x) (null x)))))
 ;;;_  = allout-file-xref-bullet
 (defcustom allout-file-xref-bullet "@"
   "Bullet signifying file cross-references, for `allout-resolve-xref'.
@@ -739,7 +746,7 @@ Set this var to the bullet you want to use for file cross-references."
 (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)))))
+       (lambda (x) (or (stringp x) (null x)))))
 ;;;_  = allout-presentation-padding
 (defcustom allout-presentation-padding 2
   "Presentation-format white-space padding factor, for greater indent."
@@ -752,7 +759,7 @@ Set this var to the bullet you want to use for file cross-references."
 
 ;;;_  = allout-flattened-numbering-abbreviation
 (define-obsolete-variable-alias 'allout-abbreviate-flattened-numbering
-  'allout-flattened-numbering-abbreviation "24.0")
+  'allout-flattened-numbering-abbreviation "24.1")
 (defcustom allout-flattened-numbering-abbreviation nil
   "If non-nil, `allout-flatten-exposed-to-buffer' abbreviates topic
 numbers to minimal amount with some context.  Otherwise, entire
@@ -816,37 +823,32 @@ formatted copy."
   :group 'allout-encryption)
 ;;;_  = allout-encrypt-unencrypted-on-saves
 (defcustom allout-encrypt-unencrypted-on-saves t
-  "When saving, should topics pending encryption be encrypted?
-
-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
-        currently being edited.  (In that case, the currently edited topic
-        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
-        one is selected, to avoid practical difficulties -- see below.
- - 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
-       passphrase in the middle of editing for, eg, autosaves.
-       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
-when auto-encryption is enabled.  (Otherwise, spurious passphrase prompts
-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,
-disable auto-saves for that file."
-
-  :type '(choice (const :tag "Yes" t)
-                 (const :tag "All except current topic" except-current)
-                 (const :tag "No" nil))
-  :version "22.1"
+  "If non-nil, topics pending encryption are encrypted during buffer saves.
+
+This provents file-system exposure of un-encrypted contents of
+items marked for encryption.
+
+When non-nil, if the topic currently being edited is decrypted,
+it will be encrypted for saving but automatically decrypted
+before any subsequent user interaction, so it is once again clear
+text for editing though the file system copy is encrypted.
+
+\(Auto-saves are handled differently.  Buffers with plain-text
+exposed encrypted topics are exempted from auto saves until all
+such topics are encrypted.)"
+
+  :type 'boolean
+  :version "23.1"
   :group 'allout-encryption)
 (make-variable-buffer-local 'allout-encrypt-unencrypted-on-saves)
+(defvar allout-auto-save-temporarily-disabled nil
+  "True while topic encryption is pending and auto-saving was active.
+
+The value of buffer-saved-size at the time of decryption is used,
+for restoring when all encryptions are established.")
+(defvar allout-just-did-undo nil
+  "True just after undo commands, until allout-post-command-business.")
+(make-variable-buffer-local 'allout-just-did-undo)
 
 ;;;_ + Developer
 ;;;_  = allout-developer group
@@ -934,7 +936,7 @@ case the value of `allout-default-layout' is used.")
 (make-variable-buffer-local 'allout-layout)
 ;;;###autoload
 (put 'allout-layout 'safe-local-variable
-     '(lambda (x) (or (numberp x) (listp x) (memq x '(: * + -)))))
+     (lambda (x) (or (numberp x) (listp x) (memq x '(: * + -)))))
 
 ;;;_  : Topic header format
 ;;;_   = allout-regexp
@@ -1402,7 +1404,7 @@ their settings before allout-mode was started."
 (defvar allout-mode-deactivate-hook nil
   "*Hook that's run when allout mode ends.")
 (define-obsolete-variable-alias 'allout-mode-deactivate-hook
-  'allout-mode-off-hook "future")
+  'allout-mode-off-hook "24.1")
 ;;;_   = allout-exposure-category
 (defvar allout-exposure-category nil
   "Symbol for use as allout invisible-text overlay category.")
@@ -1459,7 +1461,15 @@ This hook might be invoked multiple times by a single command.")
 (defvar allout-after-copy-or-kill-hook nil
   "*Hook that's run after copying outline text.
 
-Functions on the hook should not take any arguments.")
+Functions on the hook should not require any arguments.")
+;;;_   = allout-post-undo-hook
+(defvar allout-post-undo-hook nil
+  "*Hook that's run after undo activity.
+
+The item that's current when the hook is run *may* be the one
+that was affected by the undo.
+
+Functions on the hook should not require any arguments.")
 ;;;_   = allout-outside-normal-auto-fill-function
 (defvar allout-outside-normal-auto-fill-function nil
   "Value of normal-auto-fill-function outside of allout mode.
@@ -1557,39 +1567,43 @@ See `allout-encryption-ciphertext-rejection-regexps' for rejection reasons.")
 (defmacro allout-mode-p ()
   "Return t if `allout-mode' is active in current buffer."
   'allout-mode)
-;;;_   > allout-write-file-hook-handler ()
-(defun allout-write-file-hook-handler ()
-  "Implement `allout-encrypt-unencrypted-on-saves' policy for file writes."
+;;;_   > allout-write-contents-hook-handler ()
+(defun allout-write-contents-hook-handler ()
+  "Implement `allout-encrypt-unencrypted-on-saves' for file writes
+
+Return nil if all goes smoothly, or else return an informative
+message if an error is encountered.  The message will serve as a
+non-nil return on `write-contents-functions' to prevent saving of
+the buffer while it has decrypted content.
+
+This behavior depends on emacs versions that implement the
+`write-contents-functions' hook."
 
   (if (or (not (allout-mode-p))
           (not (boundp 'allout-encrypt-unencrypted-on-saves))
           (not allout-encrypt-unencrypted-on-saves))
       nil
-    (let ((except-mark (and (equal allout-encrypt-unencrypted-on-saves
-                                   'except-current)
-                            (point-marker))))
-      (if (save-excursion (goto-char (point-min))
-                          (allout-next-topic-pending-encryption except-mark))
-          (progn
-            (message "auto-encrypting pending topics")
-            (sit-for 0)
-            (condition-case failure
+    (if (save-excursion (goto-char (point-min))
+                        (allout-next-topic-pending-encryption))
+        (progn
+          (message "auto-encrypting pending topics")
+          (sit-for 0)
+          (condition-case failure
+              (progn
                 (setq allout-after-save-decrypt
-                      (allout-encrypt-decrypted except-mark))
-              (error (message
-                      "allout-write-file-hook-handler suppressing error %s"
-                      failure)
-                     (sit-for 2)))))
-      ))
-  nil)
-;;;_   > allout-auto-save-hook-handler ()
-(defun allout-auto-save-hook-handler ()
-  "Implement `allout-encrypt-unencrypted-on-saves' policy for auto save."
-
-  (if (and (allout-mode-p) allout-encrypt-unencrypted-on-saves)
-      ;; Always implement 'except-current policy when enabled.
-      (let ((allout-encrypt-unencrypted-on-saves 'except-current))
-        (allout-write-file-hook-handler))))
+                      (allout-encrypt-decrypted))
+                ;; aok - return nil:
+                nil)
+            (error
+             ;; whoops - probably some still-decrypted items, return non-nil:
+             (let ((text (format (concat "%s contents write inhibited due to"
+                                         " encrypted topic encryption error:"
+                                         " %s")
+                                 (buffer-name (current-buffer))
+                                 failure)))
+               (message text)(sit-for 2)
+               text)))))
+    ))
 ;;;_   > allout-after-saves-handler ()
 (defun allout-after-saves-handler ()
   "Decrypt topic encrypted for save, if it's currently being edited.
@@ -1642,7 +1656,7 @@ So `allout-post-command-business' should not reactivate it...")
 (defun allout-init (mode)
   "DEPRECATED - configure allout activation by customizing
 `allout-auto-activation'.  This function remains around, limited
-from what it did before, for backwards compatability.
+from what it did before, for backwards compatibility.
 
 MODE is the activation mode - see `allout-auto-activation' for
 valid values."
@@ -1868,6 +1882,7 @@ without changes to the allout core.  Here are key ones:
 `allout-structure-deleted-hook'
 `allout-structure-shifted-hook'
 `allout-after-copy-or-kill-hook'
+`allout-post-undo-hook'
 
                             Terminology
 
@@ -1953,12 +1968,7 @@ OPEN:    A TOPIC that is not CLOSED, though its OFFSPRING or BODY may be."
   :lighter " Allout"
   :keymap 'allout-mode-map
 
-  (let ((write-file-hook-var-name (cond ((boundp 'write-file-functions)
-                                         'write-file-functions)
-                                        ((boundp 'write-file-hooks)
-                                         'write-file-hooks)
-                                        (t 'local-write-file-hooks)))
-        (use-layout (if (listp allout-layout)
+  (let ((use-layout (if (listp allout-layout)
                         allout-layout
                       allout-default-layout)))
 
@@ -1977,9 +1987,8 @@ OPEN:     A TOPIC that is not CLOSED, though its OFFSPRING or BODY may be."
           (remove-hook 'post-command-hook 'allout-post-command-business t)
           (remove-hook 'before-change-functions 'allout-before-change-handler t)
           (remove-hook 'isearch-mode-end-hook 'allout-isearch-end-handler t)
-          (remove-hook write-file-hook-var-name
-                       'allout-write-file-hook-handler t)
-          (remove-hook 'auto-save-hook 'allout-auto-save-hook-handler t)
+          (remove-hook 'write-contents-functions
+                       'allout-write-contents-hook-handler t)
 
           (remove-overlays (point-min) (point-max)
                            'category 'allout-exposure-category))
@@ -2012,9 +2021,8 @@ OPEN:     A TOPIC that is not CLOSED, though its OFFSPRING or BODY may be."
       (add-hook 'post-command-hook 'allout-post-command-business nil t)
       (add-hook 'before-change-functions 'allout-before-change-handler nil t)
       (add-hook 'isearch-mode-end-hook 'allout-isearch-end-handler nil t)
-      (add-hook write-file-hook-var-name 'allout-write-file-hook-handler
+      (add-hook 'write-contents-functions 'allout-write-contents-hook-handler
                 nil t)
-      (add-hook 'auto-save-hook 'allout-auto-save-hook-handler nil t)
 
       ;; Stash auto-fill settings and adjust so custom allout auto-fill
       ;; func will be used if auto-fill is active or activated.  (The
@@ -2078,7 +2086,7 @@ OPEN:     A TOPIC that is not CLOSED, though its OFFSPRING or BODY may be."
   (save-current-buffer
     (dolist (buffer (buffer-list))
       (set-buffer buffer)
-      (when (allout-mode-p) (allout-mode))))
+      (when (allout-mode-p) (allout-mode -1))))
   ;; continue standard unloading
   nil)
 
@@ -2147,8 +2155,10 @@ internal functions use this feature cohesively bunch changes."
 
 See `allout-overlay-interior-modification-handler' for details."
 
-  (when (and (allout-mode-p) undo-in-progress (allout-hidden-p))
-    (allout-show-children))
+  (when (and (allout-mode-p) undo-in-progress)
+    (setq allout-just-did-undo t)
+    (if (allout-hidden-p)
+        (allout-show-children)))
 
   ;; allout-overlay-interior-modification-handler on an overlay handles
   ;; this in other emacs, via `allout-exposure-category's 'modification-hooks.
@@ -3125,7 +3135,7 @@ situation."
                  nil)
         ;; rationale: if any intervening items were at a lower depth, we
         ;; would now be on the first offspring at the target depth -- ie,
-        ;; the preceeding item (per the search direction) must be at a
+        ;; the preceding item (per the search direction) must be at a
         ;; lesser depth.  that's all we need to check.
         (if backward (allout-next-heading) (allout-previous-heading))
         (if (< allout-recent-depth target-depth)
@@ -3294,6 +3304,10 @@ are mapped to the command of the corresponding control-key on the
 Set by `allout-pre-command-business', to support allout addons in
 coordinating with allout activity.")
 (make-variable-buffer-local 'allout-command-counter)
+;;;_   = allout-this-command-hid-text
+(defvar allout-this-command-hid-text nil
+  "True if the most recent allout-mode command hid any text.")
+(make-variable-buffer-local 'allout-this-command-hid-text)
 ;;;_   > allout-post-command-business ()
 (defun allout-post-command-business ()
   "Outline `post-command-hook' function.
@@ -3301,12 +3315,33 @@ coordinating with allout activity.")
 - Implement (and clear) `allout-post-goto-bullet', for hot-spot
   outline commands.
 
+- Move the cursor to the beginning of the entry if it is hidden
+  and collapsing activity just happened.
+
+- If the command we're following was an undo, check for change in
+  the status of encrypted items and adjust auto-save inhibitions
+  accordingly.
+
 - Decrypt topic currently being edited if it was encrypted for a save."
 
-                                       ; Apply any external change func:
   (if (not (allout-mode-p))            ; In allout-mode.
       nil
 
+    (when allout-just-did-undo
+      (setq allout-just-did-undo nil)
+      (run-hooks 'allout-post-undo-hook)
+      (cond ((and (= buffer-saved-size -1)
+                  allout-auto-save-temporarily-disabled)
+             ;; user possibly undid a decryption, deinhibit auto-save:
+             (allout-maybe-resume-auto-save-info-after-encryption))
+            ((save-excursion
+               (save-restriction
+                 (widen)
+                 (goto-char (point-min))
+                 (not (allout-next-topic-pending-encryption))))
+             ;; plain-text encrypted items are present, inhibit auto-save:
+             (allout-inhibit-auto-save-info-for-decryption (buffer-size)))))
+
     (if (and (boundp 'allout-after-save-decrypt)
              allout-after-save-decrypt)
         (allout-after-saves-handler))
@@ -3315,8 +3350,9 @@ coordinating with allout activity.")
     (if (and allout-post-goto-bullet
             (allout-current-bullet-pos))
        (progn (goto-char (allout-current-bullet-pos))
-              (setq allout-post-goto-bullet nil)))
-    ))
+              (setq allout-post-goto-bullet nil))
+      (when (and (allout-hidden-p) allout-this-command-hid-text)
+        (allout-beginning-of-current-entry)))))
 ;;;_   > allout-pre-command-business ()
 (defun allout-pre-command-business ()
   "Outline `pre-command-hook' function for outline buffers.
@@ -3339,8 +3375,8 @@ return to regular interpretation of self-insert characters."
 
   (if (not (allout-mode-p))
       nil
-    ;; Increment allout-command-counter
     (setq allout-command-counter (1+ allout-command-counter))
+    (setq allout-this-command-hid-text nil)
     ;; Do hot-spot navigation.
     (if (and (eq this-command 'self-insert-command)
             (eq (point)(allout-current-bullet-pos)))
@@ -3465,13 +3501,13 @@ Offer one suitable for current depth DEPTH as default."
 (defun allout-make-topic-prefix (&optional prior-bullet
                                             new
                                             depth
-                                            solicit
+                                            instead
                                             number-control
                                             index)
   ;; Depth null means use current depth, non-null means we're either
   ;; opening a new topic after current topic, lower or higher, or we're
   ;; changing level of current topic.
-  ;; Solicit dominates specified bullet-char.
+  ;; Instead dominates specified bullet-char.
 ;;;_    . Doc string:
   "Generate a topic prefix suitable for optional arg DEPTH, or current depth.
 
@@ -3492,15 +3528,18 @@ bullet or previous sibling.
 Third arg DEPTH forces the topic prefix to that depth, regardless of
 the current topics' depth.
 
-If SOLICIT is non-nil, then the choice of bullet is solicited from
-user.  If it's a character, then that character is offered as the
-default, otherwise the one suited to the context (according to
-distinction or depth) is offered.  (This overrides other options,
-including, eg, a distinctive PRIOR-BULLET.)  If non-nil, then the
-context-specific bullet is used.
+If INSTEAD is:
+
+- nil, then the bullet char for the context is used, per distinction or depth
+- a \(numeric) character, then character's string representation is used
+- a string, then the user is asked for bullet with the first char as default
+- anything else, the user is solicited with bullet char per context as default
+
+\(INSTEAD overrides other options, including, eg, a distinctive
+PRIOR-BULLET.)
 
 Fifth arg, NUMBER-CONTROL, matters only if `allout-numbered-bullet'
-is non-nil *and* soliciting was not explicitly invoked.  Then
+is non-nil *and* no specific INSTEAD was specified.  Then
 NUMBER-CONTROL non-nil forces prefix to either numbered or
 denumbered format, depending on the value of the sixth arg, INDEX.
 
@@ -3549,8 +3588,13 @@ index for each successive sibling)."
            ;; Solicitation overrides numbering and other cases:
            ((progn (setq body (make-string (- depth 2) ?\ ))
                    ;; The actual condition:
-                   solicit)
-            (let* ((got (allout-solicit-alternate-bullet depth solicit)))
+                   instead)
+            (let ((got (cond ((stringp instead)
+                              (if (> (length instead) 0)
+                                  (allout-solicit-alternate-bullet
+                                   depth (substring instead 0 1))))
+                             ((characterp instead) (char-to-string instead))
+                             (t (allout-solicit-alternate-bullet depth)))))
               ;; Gotta check whether we're numbering and got a numbered bullet:
               (setq numbering (and allout-numbered-bullet
                                    (not (and number-control (not index)))
@@ -3839,7 +3883,9 @@ topic prior to the current one."
 Maintains outline hanging topic indentation if
 `allout-use-hanging-indents' is set."
 
-  (when (not allout-inhibit-auto-fill)
+  (when (and (not allout-inhibit-auto-fill)
+             (or (not allout-inhibit-auto-fill-on-headline)
+                 (not (allout-on-current-heading-p))))
     (let ((fill-prefix (if allout-use-hanging-indents
                            ;; Check for topic header indentation:
                            (save-match-data
@@ -3913,7 +3959,7 @@ Note that refill of indented paragraphs is not done."
                      (allout-end-of-prefix)
                       (setq from allout-recent-prefix-beginning
                             to allout-recent-prefix-end)
-                     (allout-rebullet-heading t        ;;; solicit
+                     (allout-rebullet-heading t        ;;; instead
                                                nil     ;;; depth
                                                nil     ;;; number-control
                                                nil     ;;; index
@@ -3931,8 +3977,8 @@ Note that refill of indented paragraphs is not done."
     (message "Done.")
     (cond (on-bullet (goto-char (allout-current-bullet-pos)))
          (initial-col (move-to-column initial-col)))))
-;;;_    > allout-rebullet-heading (&optional solicit ...)
-(defun allout-rebullet-heading (&optional solicit
+;;;_    > allout-rebullet-heading (&optional instead ...)
+(defun allout-rebullet-heading (&optional instead
                                            new-depth
                                            number-control
                                            index
@@ -3942,11 +3988,11 @@ Note that refill of indented paragraphs is not done."
 
 All args are optional.
 
-If SOLICIT is non-nil, then the choice of bullet is solicited from
-user.  If it's a character, then that character is offered as the
-default, otherwise the one suited to the context (according to
-distinction or depth) is offered.  If non-nil, then the
-context-specific bullet is just used.
+If INSTEAD is:
+- nil, then the bullet char for the context is used, per distinction or depth
+- a \(numeric) character, then character's string representation is used
+- a string, then the user is asked for bullet with the first char as default
+- anything else, the user is solicited with bullet char per context as default
 
 Second arg DEPTH forces the topic prefix to that depth, regardless
 of the topic's current depth.
@@ -3981,7 +4027,7 @@ this function."
          (new-prefix (allout-make-topic-prefix current-bullet
                                                 nil
                                                 new-depth
-                                                solicit
+                                                instead
                                                 number-control
                                                 index)))
 
@@ -4019,6 +4065,8 @@ this function."
                (not (allout-encrypted-topic-p)))
          (allout-reindent-body current-depth new-depth))
 
+      (run-hook-with-args 'allout-exposure-change-hook mb me nil)
+
       ;; Recursively rectify successive siblings of orig topic if
       ;; caller elected for it:
       (if do-successors
@@ -4028,7 +4076,7 @@ this function."
                    (cond ((numberp index) (1+ index))
                          ((not number-control)  (allout-sibling-index))))
              (if (allout-numbered-type-prefix)
-                 (allout-rebullet-heading nil          ;;; solicit
+                 (allout-rebullet-heading nil          ;;; instead
                                            new-depth   ;;; new-depth
                                            number-control;;; number-control
                                            index       ;;; index
@@ -4145,7 +4193,7 @@ a topic and its immediate offspring is greater than one.)"
            (when (< relative-depth 0)
              (save-excursion
                (goto-char local-point)
-               (allout-rebullet-heading nil               ;;; solicit
+               (allout-rebullet-heading nil               ;;; instead
                                         (+ starting-depth relative-depth)
                                         nil            ;;; number
                                         starting-index
@@ -4203,7 +4251,7 @@ Returns final depth."
                                         ; Prime ascender for ascension:
       (setq ascender (1- allout-recent-depth))
       (if (>= allout-recent-depth depth)
-          (allout-rebullet-heading nil ;;; solicit
+          (allout-rebullet-heading nil ;;; instead
                                     nil        ;;; depth
                                     nil        ;;; number-control
                                     nil        ;;; index
@@ -4230,7 +4278,7 @@ rebulleting each topic at this level."
           (use-bullet (equal '(16) denumber))
           (more t))
       (while more
-        (allout-rebullet-heading use-bullet            ;;; solicit
+        (allout-rebullet-heading use-bullet            ;;; instead
                                   depth                        ;;; depth
                                   t                    ;;; number-control
                                   index                        ;;; index
@@ -4246,7 +4294,7 @@ With a negative argument, the item is shifted out using
 
 With an argument greater than one, shift-in the item but not its
 offspring, making the item into a sibling of its former children,
-and a child of sibling that formerly preceeded it.
+and a child of sibling that formerly preceded it.
 
 You are not allowed to shift the first offspring of a topic
 inwards, because that would yield a \"containment
@@ -4480,8 +4528,9 @@ Topic exposure is marked with text-properties, to be used by
             ;; advance to just after end of this annotation:
             (setq next (allout-next-single-char-property-change
                         (point) 'allout-was-hidden nil end))
-            (overlay-put (make-overlay prev next nil 'front-advance)
-                         'category 'allout-exposure-category)
+            (let ((o (make-overlay prev next nil 'front-advance)))
+              (overlay-put o 'category 'allout-exposure-category)
+              (overlay-put o 'evaporate t))
             (allout-deannotate-hidden prev next)
             (setq prev next)
             (if next (goto-char next)))))
@@ -4577,32 +4626,21 @@ however, are left exactly like normal, non-allout-specific yanks."
                           (progn (widen)
                                  (forward-char -1)
                                  (narrow-to-region subj-beg (point))))))
-                  ;; Preserve new bullet if it's a distinctive one, otherwise
-                  ;; use old one:
-                  (if (string-match (regexp-quote prefix-bullet)
-                                    allout-distinctive-bullets-string)
-                                        ; Delete from bullet of old to
-                                        ; before bullet of new:
-                      (progn
-                        (beginning-of-line)
-                        (allout-unprotected
-                         (delete-region (point) subj-beg))
-                        (set-marker (allout-mark-marker t) subj-end)
-                        (goto-char subj-beg)
-                        (allout-end-of-prefix))
-                                        ; Delete base subj prefix,
-                                        ; leaving old one:
-                    (allout-unprotected
-                     (progn
-                       (delete-region (point) (+ (point)
-                                                 prefix-len
-                                                 (- adjust-to-depth
-                                                    subj-depth)))
+                  ;; Remove new heading prefix:
+                  (allout-unprotected
+                   (progn
+                     (delete-region (point) (+ (point)
+                                               prefix-len
+                                               (- adjust-to-depth
+                                                  subj-depth)))
                                         ; and delete residual subj
                                         ; prefix digits and space:
-                       (while (looking-at "[0-9]") (delete-char 1))
-                       (if (looking-at " ")
-                           (delete-char 1))))))
+                     (while (looking-at "[0-9]") (delete-char 1))
+                     (delete-char -1)
+                     (if (not (eolp))
+                         (forward-char))))
+                  ;; Assert new topic's bullet - minimal effort if unchanged:
+                  (allout-rebullet-heading (string-to-char prefix-bullet)))
               (exchange-point-and-mark))))
       (if rectify-numbering
           (progn
@@ -4613,7 +4651,7 @@ however, are left exactly like normal, non-allout-specific yanks."
               (goto-char subj-beg)
               (if (allout-goto-prefix-doublechecked)
                   (allout-unprotected
-                   (allout-rebullet-heading nil          ;;; solicit
+                   (allout-rebullet-heading nil          ;;; instead
                                             (allout-depth) ;;; depth
                                             nil ;;; number-control
                                             nil ;;; index
@@ -4730,13 +4768,15 @@ arguments as this function, after the exposure changes are made."
   (when flag
     (let ((o (make-overlay from to nil 'front-advance)))
       (overlay-put o 'category 'allout-exposure-category)
+      (overlay-put o 'evaporate t)
       (when (featurep 'xemacs)
         (let ((props (symbol-plist 'allout-exposure-category)))
           (while props
             (condition-case nil
                 ;; as of 2008-02-27, xemacs lacks modification-hooks
                 (overlay-put o (pop props) (pop props))
-              (error nil)))))))
+              (error nil))))))
+    (setq allout-this-command-hid-text t))
   (run-hook-with-args 'allout-exposure-change-hook from to flag))
 ;;;_   > allout-flag-current-subtree (flag)
 (defun allout-flag-current-subtree (flag)
@@ -5364,7 +5404,7 @@ header and body.  The elements of that list are:
 
       (goto-char start)
       (beginning-of-line)
-      ;; Goto initial topic, and register preceeding stuff, if any:
+      ;; Goto initial topic, and register preceding stuff, if any:
       (if (> (allout-goto-prefix-doublechecked) start)
          ;; First topic follows beginning point -- register preliminary stuff:
          (setq result
@@ -5889,6 +5929,8 @@ See `allout-toggle-current-subtree-encryption' for more details."
                        " shift it in to make it encryptable")))
 
     (let* ((allout-buffer (current-buffer))
+           ;; for use with allout-auto-save-temporarily-disabled, if necessary:
+           (was-buffer-saved-size buffer-saved-size)
            ;; Assess location:
            (bullet-pos allout-recent-prefix-beginning)
            (after-bullet-pos (point))
@@ -5968,6 +6010,12 @@ See `allout-toggle-current-subtree-encryption' for more details."
            ;; Add the is-encrypted bullet qualifier:
            (goto-char after-bullet-pos)
            (insert "*"))))
+
+      ;; adjust buffer's auto-save eligibility:
+      (if was-encrypted
+          (allout-inhibit-auto-save-info-for-decryption was-buffer-saved-size)
+        (allout-maybe-resume-auto-save-info-after-encryption))
+
       (run-hook-with-args 'allout-structure-added-hook
                           bullet-pos subtree-end))))
 ;;;_  > allout-encrypt-string (text decrypt allout-buffer keymode-cue
@@ -6019,6 +6067,7 @@ signal."
                         (epg-context-set-passphrase-callback
                          context #'epa-passphrase-callback-function)
                         context))
+
          (encoding (with-current-buffer allout-buffer
                      buffer-file-coding-system))
          (multibyte (with-current-buffer allout-buffer
@@ -6140,8 +6189,29 @@ signal."
                          result-text))
       (error (concat "Encryption produced non-armored text, which"
                      "conflicts with allout mode -- reconfigure!")))
-
      (t result-text))))
+;;;_  > allout-inhibit-auto-save-info-for-decryption
+(defun allout-inhibit-auto-save-info-for-decryption (was-buffer-saved-size)
+  "Temporarily prevent auto-saves in this buffer when an item is decrypted.
+
+WAS-BUFFER-SAVED-SIZE is the value of buffer-saved-size *before*
+the decryption."
+  (when (not (or (= buffer-saved-size -1) (= was-buffer-saved-size -1)))
+    (setq allout-auto-save-temporarily-disabled was-buffer-saved-size
+          buffer-saved-size -1)))
+;;;_  > allout-maybe-resume-auto-save-info-after-encryption ()
+(defun allout-maybe-resume-auto-save-info-after-encryption ()
+  "Restore auto-save info, *if* there are no topics pending encryption."
+  (when (and allout-auto-save-temporarily-disabled
+             (= buffer-saved-size -1)
+             (save-excursion
+               (save-restriction
+                 (widen)
+                 (goto-char (point-min))
+                 (not (allout-next-topic-pending-encryption)))))
+    (setq buffer-saved-size allout-auto-save-temporarily-disabled
+          allout-auto-save-temporarily-disabled nil)))
+
 ;;;_  > allout-encrypted-topic-p ()
 (defun allout-encrypted-topic-p ()
   "True if the current topic is encryptable and encrypted."
@@ -6152,14 +6222,10 @@ signal."
          (save-match-data (looking-at "\\*")))
     )
   )
-;;;_  > allout-next-topic-pending-encryption (&optional except-mark)
-(defun allout-next-topic-pending-encryption (&optional except-mark)
+;;;_  > allout-next-topic-pending-encryption ()
+(defun allout-next-topic-pending-encryption ()
   "Return the point of the next topic pending encryption, or nil if none.
 
-EXCEPT-MARK identifies a point whose containing topics should be excluded
-from encryption.  This supports 'except-current mode of
-`allout-encrypt-unencrypted-on-saves'.
-
 Such a topic has the `allout-topic-encryption-bullet' without an
 immediately following '*' that would mark the topic as being encrypted.  It
 must also have content."
@@ -6194,10 +6260,7 @@ must also have content."
                (setq content-beg (point))
                (backward-char 1)
                (allout-end-of-subtree)
-               (if (or (<= (point) content-beg)
-                       (and except-mark
-                            (<= content-beg except-mark)
-                            (>= (point) except-mark)))
+               (if (<= (point) content-beg)
                    ;; Continue looking
                    (setq got nil)
                  ;; Got it!
@@ -6209,14 +6272,10 @@ must also have content."
       )
     )
   )
-;;;_  > allout-encrypt-decrypted (&optional except-mark)
-(defun allout-encrypt-decrypted (&optional except-mark)
+;;;_  > allout-encrypt-decrypted ()
+(defun allout-encrypt-decrypted ()
   "Encrypt topics pending encryption except those containing exemption point.
 
-EXCEPT-MARK identifies a point whose containing topics should be excluded
-from encryption.  This supports the `except-current' mode of
-`allout-encrypt-unencrypted-on-saves'.
-
 If a topic that is currently being edited was encrypted, we return a list
 containing the location of the topic and the location of the cursor just
 before the topic was encrypted.  This can be used, eg, to decrypt the topic
@@ -6232,7 +6291,7 @@ save.  See `allout-encrypt-unencrypted-on-saves' for more info."
              bo-subtree
              editing-topic editing-point)
         (goto-char (point-min))
-        (while (allout-next-topic-pending-encryption except-mark)
+        (while (allout-next-topic-pending-encryption)
           (setq was-modified (buffer-modified-p))
           (when (save-excursion
                   (and (boundp 'allout-encrypt-unencrypted-on-saves)
@@ -6509,7 +6568,7 @@ If BEG is bigger than END we return 0."
 (defun allout-mark-marker (&optional force buffer)
   "Accommodate the different signature for `mark-marker' across Emacsen.
 
-XEmacs takes two optional args, while mainline GNU Emacs does not,
+XEmacs takes two optional args, while Emacs does not,
 so pass them along when appropriate."
   (if (featurep 'xemacs)
       (apply 'mark-marker force buffer)