summaryrefslogtreecommitdiff
path: root/lisp/allout.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/allout.el')
-rw-r--r--lisp/allout.el1428
1 files changed, 482 insertions, 946 deletions
diff --git a/lisp/allout.el b/lisp/allout.el
index b497c82f0b3..d965ac35338 100644
--- a/lisp/allout.el
+++ b/lisp/allout.el
@@ -1,12 +1,11 @@
;;; allout.el --- extensive outline mode for use alone and with other modes
-;; Copyright (C) 1992, 1993, 1994, 2001, 2002, 2003, 2004, 2005, 2006,
-;; 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 1992-1994, 2001-2011 Free Software Foundation, Inc.
;; Author: Ken Manheimer <ken dot manheimer at gmail dot com>
;; Maintainer: Ken Manheimer <ken dot manheimer at gmail dot com>
;; Created: Dec 1991 -- first release to usenet
-;; Version: 2.2.2
+;; Version: 2.3
;; Keywords: outlines wp languages
;; Website: http://myriadicity.net/Sundry/EmacsAllout
@@ -43,9 +42,8 @@
;; - Symmetric-key and key-pair topic encryption, plus symmetric passphrase
;; mnemonic support, with verification against an established passphrase
;; (using a stashed encrypted dummy string) and user-supplied hint
-;; maintenance. (See allout-toggle-current-subtree-encryption docstring.
-;; Currently only GnuPG encryption is supported, and integration
-;; with gpg-agent is not yet implemented.)
+;; maintenance. Encryption is via the Emacs 'epg' library. See
+;; allout-toggle-current-subtree-encryption docstring.
;; - Automatic topic-number maintenance
;; - "Hot-spot" operation, for single-keystroke maneuvering and
;; exposure control (see the allout-mode docstring)
@@ -84,11 +82,10 @@
;;;_* Dependency autoloads
(require 'overlay)
(eval-when-compile
- ;; Most of the requires here are for stuff covered by autoloads.
- ;; Since just byte-compiling doesn't trigger autoloads, so that
- ;; "function not found" warnings would occur without these requires.
- (require 'pgg)
- (require 'pgg-gpg)
+ ;; Most of the requires here are for stuff covered by autoloads, which
+ ;; byte-compiling doesn't trigger.
+ (require 'epg)
+ (require 'epa)
(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
@@ -110,23 +107,39 @@
;;;_ + Layout, Mode, and Topic Header Configuration
(defvar allout-command-prefix) ; defined below
-(defvar allout-mode-map)
;;;_ > 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
+;;;_ : internal key binding stuff - in this section for load-order.
+;;;_ = allout-mode-map
+(defvar allout-mode-map 'allout-mode-map
+ "Keybindings place-holder for (allout) outline minor mode.
+
+Do NOT set the value of this variable. Instead, customize
+`allout-command-prefix', `allout-prefixed-keybindings', and
+`allout-unprefixed-keybindings'.")
+;;;_ = allout-mode-map-value
+(defvar allout-mode-map-value nil
+ "Keymap for allout outline minor mode.
+
+Do NOT set the value of this variable. Instead, customize
+`allout-command-prefix', `allout-prefixed-keybindings', and
+`allout-unprefixed-keybindings'.")
+;;;_ = make allout-mode-map-value an alias for allout-mode-map:
+;; this needs to be revised when the value is changed, sigh.
+(defalias 'allout-mode-map allout-mode-map-value)
+;;;_ > allout-compose-and-institute-keymap (&optional varname value)
+(defun allout-compose-and-institute-keymap (&optional varname value)
+ "Create the allout keymap according to the keybinding specs, and set it.
+
+Useful standalone or to effect customizations of 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)
+ (let ((map (make-sparse-keymap)))
(when (boundp 'allout-prefixed-keybindings)
- ;; Be tolerant of the moments when the variables are first being defined.
+ ;; tolerate first definitions of the variables:
(dolist (entry allout-prefixed-keybindings)
(define-key map
;; XXX vector vs non-vector key descriptions?
@@ -136,9 +149,34 @@ respective allout-mode keybinding variables, `allout-command-prefix',
(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
- ))
+ (substitute-key-definition 'beginning-of-line 'allout-beginning-of-line
+ map global-map)
+ (substitute-key-definition 'move-beginning-of-line 'allout-beginning-of-line
+ map global-map)
+ (substitute-key-definition 'end-of-line 'allout-end-of-line
+ map global-map)
+ (substitute-key-definition 'move-end-of-line 'allout-end-of-line
+ map global-map)
+ (allout-institute-keymap map)))
+;;;_ > allout-institute-keymap (map)
+(defun allout-institute-keymap (map)
+ "Associate allout-mode bindings with allout as a minor mode."
+ ;; Architecture:
+ ;; allout-mode-map var is a keymap by virtue of being a defalias for
+ ;; allout-mode-map-value, which has the actual keymap value.
+ ;; allout-mode-map's symbol value is just 'allout-mode-map, so it can be
+ ;; used in minor-mode-map-alist to indirect to the actual
+ ;; allout-mode-map-var value, which can be adjusted and reassigned.
+
+ ;; allout-mode-map-value for keymap reference in various places:
+ (setq allout-mode-map-value map)
+ ;; the function value keymap of allout-mode-map is used in
+ ;; minor-mode-map-alist - update it:
+ (fset allout-mode-map allout-mode-map-value))
+;;;_ * intialize the mode map:
+;; ensure that allout-mode-map has some setting even if allout-mode hasn't
+;; been invoked:
+(allout-compose-and-institute-keymap)
;;;_ = allout-command-prefix
(defcustom allout-command-prefix "\C-c "
"Key sequence to be used as prefix for outline mode command key bindings.
@@ -147,7 +185,7 @@ 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
:group 'allout-keybindings
- :set 'allout-bind-keys)
+ :set 'allout-compose-and-institute-keymap)
;;;_ = allout-keybindings-binding
(define-widget 'allout-keybindings-binding 'lazy
"Structure of allout keybindings customization items."
@@ -159,16 +197,16 @@ willing to let allout use a bunch of \C-c keybindings."
(defcustom allout-prefixed-keybindings
'(("[(control ?n)]" allout-next-visible-heading)
("[(control ?p)]" allout-previous-visible-heading)
-;; ("[(control ?u)]" allout-up-current-level)
+ ("[(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)
+;; Let user customize if they want to preempt describe-prefix-bindings ^h use.
+;; ("[(control ?h)]" allout-hide-current-subtree)
("[?h]" allout-hide-current-subtree)
("[(control ?o)]" allout-show-current-entry)
("[?!]" allout-show-all)
@@ -181,9 +219,9 @@ willing to let allout use a bunch of \C-c keybindings."
("[?<]" allout-shift-out)
("[(control ?m)]" allout-rebullet-topic)
("[?*]" allout-rebullet-current-heading)
- ("[?']" allout-number-siblings)
+ ("[?#]" allout-number-siblings)
("[(control ?k)]" allout-kill-topic)
- ("[??]" allout-copy-topic-as-kill)
+ ("[(meta ?k)]" allout-copy-topic-as-kill)
("[?@]" allout-resolve-xref)
("[?=?c]" allout-copy-exposed-to-buffer)
("[?=?i]" allout-indented-exposed-to-buffer)
@@ -207,14 +245,14 @@ multiple functions will not work - the last binding for a key
prevails."
:type 'allout-keybindings-binding
:group 'allout-keybindings
- :set 'allout-bind-keys
+ :set 'allout-compose-and-institute-keymap
)
;;;_ = allout-unprefixed-keybindings
(defcustom allout-unprefixed-keybindings
'(("[(control ?k)]" allout-kill-line)
- ("[??(meta ?k)]" allout-copy-line-as-kill)
+ ("[(meta ?k)]" allout-copy-line-as-kill)
("[(control ?y)]" allout-yank)
- ("[??(meta ?y)]" allout-yank-pop)
+ ("[(meta ?y)]" allout-yank-pop)
)
"Allout-mode functions bound to keys without any added prefix.
@@ -230,69 +268,9 @@ Use vector format for the keys:
See the existing keys for examples."
:type 'allout-keybindings-binding
:group 'allout-keybindings
- :set 'allout-bind-keys
+ :set 'allout-compose-and-institute-keymap
)
-;;;_ = 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
- :group 'allout)
-
-;;;_ = allout-keybindings-list
-;;; You have to reactivate allout-mode -- `(allout-mode t)' -- to
-;;; institute changes to this var.
-(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:
- ([(control i)] allout-show-children) ; xemacs translates "\C-i" to tab
- ("\C-i" allout-show-children) ; but we still need this for hotspot
- ("\C-s" allout-show-current-subtree)
- ;; 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)
- ("\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)
- ([?\M-k] allout-copy-line-as-kill t)
- ("\C-y" allout-yank t)
- ([?\M-y] allout-yank-pop t)
- ("\C-k" allout-kill-topic)
- ([?\M-k] allout-copy-topic-as-kill)
- ; 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)))
-
;;;_ = allout-auto-activation
(defcustom allout-auto-activation nil
"Regulates auto-activation modality of allout outlines -- see `allout-init'.
@@ -572,7 +550,7 @@ themselves:
`!' - exclamation point/bang -- emphatic
`[' - open square bracket -- meta-note, about item instead of item's subject
`\"' - double quote -- a quotation or other citation
- `=' - equal sign -- an assignement, equating a name with some connotation
+ `=' - equal sign -- an assignment, some kind of definition
`^' - carat -- relates to something above
Some are more elusive, but their rationale may be recognizable:
@@ -818,32 +796,6 @@ formatted copy."
:type '(choice (const nil) string)
:version "22.1"
:group 'allout-encryption)
-;;;_ = allout-passphrase-verifier-handling
-(defcustom allout-passphrase-verifier-handling t
- "Enable use of symmetric encryption passphrase verifier if non-nil.
-
-See the docstring for the `allout-enable-file-variable-adjustment'
-variable for details about allout ajustment of file variables."
- :type 'boolean
- :version "22.1"
- :group 'allout-encryption)
-(make-variable-buffer-local 'allout-passphrase-verifier-handling)
-;;;_ = allout-passphrase-hint-handling
-(defcustom allout-passphrase-hint-handling 'always
- "Dictate outline encryption passphrase reminder handling:
-
- always -- always show reminder when prompting
- needed -- show reminder on passphrase entry failure
- disabled -- never present or adjust reminder
-
-See the docstring for the `allout-enable-file-variable-adjustment'
-variable for details about allout ajustment of file variables."
- :type '(choice (const always)
- (const needed)
- (const disabled))
- :version "22.1"
- :group 'allout-encryption)
-(make-variable-buffer-local 'allout-passphrase-hint-handling)
;;;_ = allout-encrypt-unencrypted-on-saves
(defcustom allout-encrypt-unencrypted-on-saves t
"When saving, should topics pending encryption be encrypted?
@@ -920,7 +872,7 @@ For details, see `allout-toggle-current-subtree-encryption's docstring."
;;;_ #1 Internal Outline Formatting and Configuration
;;;_ : Version
;;;_ = allout-version
-(defvar allout-version "2.2.2"
+(defvar allout-version "2.3"
"Version of currently loaded outline package. (allout.el)")
;;;_ > allout-version
(defun allout-version (&optional here)
@@ -1268,36 +1220,6 @@ Also refresh various data structures that hinge on the regexp."
"[^" allout-primary-bullet "]"))
"\\)"
))))
-;;;_ : Key bindings
-;;;_ = allout-mode-map
-(defvar allout-mode-map nil "Keybindings for (allout) outline minor mode.")
-;;;_ > produce-allout-mode-map (keymap-alist &optional base-map)
-(defun produce-allout-mode-map (keymap-list &optional base-map)
- "Produce keymap for use as `allout-mode-map', from KEYMAP-LIST.
-
-Built on top of optional BASE-MAP, or empty sparse map if none specified.
-See doc string for `allout-keybindings-list' for format of binding list."
- (let ((map (or base-map (make-sparse-keymap)))
- (pref (list allout-command-prefix)))
- (mapc (function
- (lambda (cell)
- (let ((add-pref (null (cdr (cdr cell))))
- (key-suff (list (car cell))))
- (apply 'define-key
- (list map
- (apply 'vconcat (if add-pref
- (append pref key-suff)
- key-suff))
- (car (cdr cell)))))))
- keymap-list)
- map))
-;;;_ > allout-mode-map-adjustments (base-map)
-(defun allout-mode-map-adjustments (base-map)
- "Do conditional additions to specified base-map, like inclusion of \\C-h."
- (if allout-preempt-trailing-ctrl-h
- (cons '("\C-h" allout-hide-current-subtree) base-map)
- base-map)
- )
;;;_ : Menu bar
(defvar allout-mode-exposure-menu)
(defvar allout-mode-editing-menu)
@@ -1306,7 +1228,7 @@ See doc string for `allout-keybindings-list' for format of binding list."
(defun produce-allout-mode-menubar-entries ()
(require 'easymenu)
(easy-menu-define allout-mode-exposure-menu
- allout-mode-map
+ allout-mode-map-value
"Allout outline exposure menu."
'("Exposure"
["Show Entry" allout-show-current-entry t]
@@ -1317,7 +1239,7 @@ See doc string for `allout-keybindings-list' for format of binding list."
"----"
["Show All" allout-show-all t]))
(easy-menu-define allout-mode-editing-menu
- allout-mode-map
+ allout-mode-map-value
"Allout outline editing menu."
'("Headings"
["Open Sibling" allout-open-sibtopic t]
@@ -1334,7 +1256,7 @@ See doc string for `allout-keybindings-list' for format of binding list."
allout-toggle-current-subtree-encryption
(> (allout-current-depth) 1)]))
(easy-menu-define allout-mode-navigation-menu
- allout-mode-map
+ allout-mode-map-value
"Allout outline navigation menu."
'("Navigation"
["Next Visible Heading" allout-next-visible-heading t]
@@ -1351,7 +1273,7 @@ See doc string for `allout-keybindings-list' for format of binding list."
["End of Entry" allout-end-of-entry t]
["End of Subtree" allout-end-of-current-subtree t]))
(easy-menu-define allout-mode-misc-menu
- allout-mode-map
+ allout-mode-map-value
"Allout outlines miscellaneous bindings."
'("Misc"
["Version" allout-version t]
@@ -1461,17 +1383,11 @@ their settings before allout-mode was started."
;;;_ = allout-mode-deactivate-hook
(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-exposure-category
(defvar allout-exposure-category nil
"Symbol for use as allout invisible-text overlay category.")
-;;;_ x allout-view-change-hook
-(defvar allout-view-change-hook nil
- "*(Deprecated) A hook run after allout outline exposure changes.
-
-Switch to using `allout-exposure-change-hook' instead. Both hooks are
-currently respected, but the other conveys the details of the exposure
-change via explicit parameters, and this one will eventually be disabled in
-a subsequent allout version.")
;;;_ = allout-exposure-change-hook
(defvar allout-exposure-change-hook nil
"*Hook that's run after allout outline subtree exposure changes.
@@ -1484,10 +1400,7 @@ Functions on the hook must take three arguments:
- TO -- integer indicating the point of the end of the change.
- FLAG -- change mode: nil for exposure, otherwise concealment.
-This hook might be invoked multiple times by a single command.
-
-This hook is replacing `allout-view-change-hook', which is being deprecated
-and eventually will not be invoked.")
+This hook might be invoked multiple times by a single command.")
;;;_ = allout-structure-added-hook
(defvar allout-structure-added-hook nil
"*Hook that's run after addition of items to the outline.
@@ -1497,9 +1410,6 @@ Functions on the hook should take two arguments:
- NEW-START -- integer indicating position of start of the first new item.
- NEW-END -- integer indicating position of end of the last new item.
-Some edits that introduce new items may missed by this hook:
-specifically edits that native allout routines do not control.
-
This hook might be invoked multiple times by a single command.")
;;;_ = allout-structure-deleted-hook
(defvar allout-structure-deleted-hook nil
@@ -1534,11 +1444,8 @@ This hook might be invoked multiple times by a single command.")
Used by allout-auto-fill to do the mandated normal-auto-fill-function
wrapped within allout's automatic fill-prefix setting.")
(make-variable-buffer-local 'allout-outside-normal-auto-fill-function)
-;;;_ = file-var-bug hack
-(defvar allout-v18/19-file-var-hack nil
- "Horrible hack used to prevent invalid multiple triggering of outline
-mode from prop-line file-var activation. Used by `allout-mode' function
-to track repeats.")
+;;;_ = prevent redundant activation by desktop mode:
+(add-to-list 'desktop-minor-mode-handlers '(allout-mode . nil))
;;;_ = allout-passphrase-verifier-string
(defvar allout-passphrase-verifier-string nil
"Setting used to test solicited encryption passphrases against the one
@@ -1554,6 +1461,8 @@ The verifier string is retained as an Emacs file variable, as well as in
the Emacs buffer state, if file variable adjustments are enabled. See
`allout-enable-file-variable-adjustment' for details about that.")
(make-variable-buffer-local 'allout-passphrase-verifier-string)
+(make-obsolete 'allout-passphrase-verifier-string
+ 'allout-passphrase-verifier-string "23.3")
;;;###autoload
(put 'allout-passphrase-verifier-string 'safe-local-variable 'stringp)
;;;_ = allout-passphrase-hint-string
@@ -1568,6 +1477,8 @@ state, if file variable adjustments are enabled. See
`allout-enable-file-variable-adjustment' for details about that.")
(make-variable-buffer-local 'allout-passphrase-hint-string)
(setq-default allout-passphrase-hint-string "")
+(make-obsolete 'allout-passphrase-hint-string
+ 'allout-passphrase-hint-string "23.3")
;;;###autoload
(put 'allout-passphrase-hint-string 'safe-local-variable 'stringp)
;;;_ = allout-after-save-decrypt
@@ -1599,15 +1510,15 @@ substition is used against the regexp matches, a la `replace-match'.")
(defvar allout-encryption-ciphertext-rejection-regexps nil
"Variable for regexps matching plaintext to remove before encryption.
-This is for the sake of redoing encryption in cases where the ciphertext
-incidentally contains strings that would disrupt mode operation --
-for example, a line that happens to look like an allout-mode topic prefix.
+This is used to detect strings in encryption results that would
+register as allout mode structural elements, for exmple, as a
+topic prefix.
Entries must be symbols that are bound to the desired regexp values.
-The encryption will be retried up to
-`allout-encryption-ciphertext-rejection-limit' times, after which an error
-is raised.")
+Encryptions that result in matches will be retried, up to
+`allout-encryption-ciphertext-rejection-limit' times, after which
+an error is raised.")
(make-variable-buffer-local 'allout-encryption-ciphertext-rejection-regexps)
;;;_ = allout-encryption-ciphertext-rejection-ceiling
@@ -1813,24 +1724,22 @@ the following two lines in your Emacs init file:
'(allout-overlay-insert-in-front-handler)))
(put 'allout-exposure-category 'modification-hooks
'(allout-overlay-interior-modification-handler)))
-;;;_ > allout-mode (&optional toggle)
+;;;_ > define-minor-mode allout-mode
;;;_ : Defun:
;;;###autoload
-(defun allout-mode (&optional toggle)
+(define-minor-mode allout-mode
;;;_ . Doc string:
"Toggle minor mode for controlling exposure and editing of text outlines.
-\\<allout-mode-map>
+\\<allout-mode-map-value>
-Optional prefix argument TOGGLE forces the mode to re-initialize
-if it is positive, otherwise it turns the mode off. Allout
-outline mode always runs as a minor mode.
+Allout outline mode always runs as a minor mode.
-Allout outline mode provides extensive outline oriented formatting and
-manipulation. It enables structural editing of outlines, as well as
-navigation and exposure. It also is specifically aimed at
-accommodating syntax-sensitive text like programming languages. (For
-an example, see the allout code itself, which is organized as an allout
-outline.)
+Allout outline mode provides extensive outline oriented
+formatting and manipulation. It enables structural editing of
+outlines, as well as navigation and exposure. It also is
+specifically aimed at accommodating syntax-sensitive text like
+programming languages. \(For example, see the allout code itself,
+which is organized as an allout outline.)
In addition to typical outline navigation and exposure, allout includes:
@@ -1838,27 +1747,30 @@ In addition to typical outline navigation and exposure, allout includes:
repositioning, promotion/demotion, cut, and paste
- incremental search with dynamic exposure and reconcealment of hidden text
- adjustable format, so programming code can be developed in outline-structure
- - easy topic encryption and decryption
+ - easy topic encryption and decryption, symmetric or key-pair
- \"Hot-spot\" operation, for single-keystroke maneuvering and exposure control
- integral outline layout, for automatic initial exposure when visiting a file
- independent extensibility, using comprehensive exposure and authoring hooks
and many other features.
-Below is a description of the key bindings, and then explanation of
-special `allout-mode' features and terminology. See also the outline
-menubar additions for quick reference to many of the features, and see
-the docstring of the function `allout-init' for instructions on
-priming your emacs session for automatic activation of `allout-mode'.
-
-The bindings are dictated by the customizable `allout-keybindings-list'
-variable. We recommend customizing `allout-command-prefix' to use just
-`\\C-c' as the command prefix, if the allout bindings don't conflict with
-any personal bindings you have on \\C-c. In any case, outline structure
-navigation and authoring is simplified by positioning the cursor on an
-item's bullet character, the \"hot-spot\" -- then you can invoke allout
-commands with just the un-prefixed, un-control-shifted command letters.
-This is described further in the HOT-SPOT Operation section.
+Below is a description of the key bindings, and then description
+of special `allout-mode' features and terminology. See also the
+outline menubar additions for quick reference to many of the
+features, and see the docstring of the function `allout-init' for
+instructions on priming your emacs session for automatic
+activation of `allout-mode'.
+
+The bindings are those listed in `allout-prefixed-keybindings'
+and `allout-unprefixed-keybindings'. We recommend customizing
+`allout-command-prefix' to use just `\\C-c' as the command
+prefix, if the allout bindings don't conflict with any personal
+bindings you have on \\C-c. In any case, outline structure
+navigation and authoring is simplified by positioning the cursor
+on an item's bullet character, the \"hot-spot\" -- then you can
+invoke allout commands with just the un-prefixed,
+un-control-shifted command letters. This is described further in
+the HOT-SPOT Operation section.
Exposure Control:
----------------
@@ -1937,19 +1849,22 @@ M-x outlineify-sticky Activate outline mode for current buffer,
Topic Encryption
Outline mode supports gpg encryption of topics, with support for
-symmetric and key-pair modes, passphrase timeout, passphrase
-consistency checking, user-provided hinting for symmetric key
-mode, and auto-encryption of topics pending encryption on save.
+symmetric and key-pair modes, and auto-encryption of topics
+pending encryption on save.
Topics pending encryption are, by default, automatically
-encrypted during file saves. If the contents of the topic
-containing the cursor was encrypted for a save, it is
-automatically decrypted for continued editing.
-
-The aim of these measures is reliable topic privacy while
-preventing accidents like neglected encryption before saves,
-forgetting which passphrase was used, and other practical
-pitfalls.
+encrypted during file saves, including checkpoint saves, to avoid
+exposing the plain text of encrypted topics in the file system.
+If the content of the topic containing the cursor was encrypted
+for a save, it is automatically decrypted for continued editing.
+
+NOTE: A few GnuPG v2 versions improperly preserve incorrect
+symmetric decryption keys, preventing entry of the correct key on
+subsequent decryption attempts until the cache times-out. That
+can take several minutes. \(Decryption of other entries is not
+affected.) Upgrade your EasyPG version, if you can, and you can
+deliberately clear your gpg-agent's cache by sending it a '-HUP'
+signal.
See `allout-toggle-current-subtree-encryption' function docstring
and `allout-encrypt-unencrypted-on-saves' customization variable
@@ -1987,7 +1902,8 @@ hooks, by which independent code can cooperate with allout
without changes to the allout core. Here are key ones:
`allout-mode-hook'
-`allout-mode-deactivate-hook'
+`allout-mode-deactivate-hook' \(deprecated)
+`allout-mode-off-hook'
`allout-exposure-change-hook'
`allout-structure-added-hook'
`allout-structure-deleted-hook'
@@ -2074,76 +1990,41 @@ CONCEALED:
CLOSED: A TOPIC whose immediate OFFSPRING and body-text is CONCEALED.
OPEN: A TOPIC that is not CLOSED, though its OFFSPRING or BODY may be."
;;;_ . Code
- (interactive "P")
-
- (let* ((active (and (not (equal major-mode 'outline))
- (allout-mode-p)))
- ; Massage universal-arg `toggle' val:
- (toggle (and toggle
- (or (and (listp toggle)(car toggle))
- toggle)))
- ; Activation specifically demanded?
- (explicit-activation (and toggle
- (or (symbolp toggle)
- (and (wholenump toggle)
- (not (zerop toggle))))))
- ;; allout-mode already called once during this complex command?
- (same-complex-command (eq allout-v18/19-file-var-hack
- (car command-history)))
- (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)))
- do-layout
- )
-
- ; See comments below re v19.18,.19 bug.
- (setq allout-v18/19-file-var-hack (car command-history))
-
- (cond
-
- ;; Provision for v19.18, 19.19 bug --
- ;; 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
- ; as last time `allout-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.
- t)
-
- ;; Deactivation:
- ((and (not explicit-activation)
- (or active toggle))
- ; Activation not explicitly
- ; requested, and either in
- ; active state or *de*activation
- ; specifically requested:
- (setq allout-explicitly-deactivated t)
-
- (allout-do-resumptions)
-
- (remove-from-invisibility-spec '(allout . t))
- (remove-hook 'pre-command-hook 'allout-pre-command-business t)
- (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-overlays (point-min) (point-max)
- 'category 'allout-exposure-category)
-
- (setq allout-mode nil)
- (run-hooks 'allout-mode-deactivate-hook))
-
- ;; Activation:
- ((not active)
- (setq allout-explicitly-deactivated nil)
+ :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)
+ allout-layout
+ allout-default-layout)))
+
+ (if (not (allout-mode-p))
+ (progn
+ ;; Deactivation:
+
+ ; Activation not explicitly
+ ; requested, and either in
+ ; active state or *de*activation
+ ; specifically requested:
+ (allout-do-resumptions)
+
+ (remove-from-invisibility-spec '(allout . t))
+ (remove-hook 'pre-command-hook 'allout-pre-command-business t)
+ (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-overlays (point-min) (point-max)
+ 'category 'allout-exposure-category))
+
+ ;; Activating:
(if allout-old-style-prefixes
;; Inhibit all the fancy formatting:
(allout-add-resumptions '(allout-primary-bullet "*")))
@@ -2154,45 +2035,31 @@ OPEN: A TOPIC that is not CLOSED, though its OFFSPRING or BODY may be."
(allout-infer-body-reindent)
(set-allout-regexp)
- (allout-add-resumptions
- '(allout-encryption-ciphertext-rejection-regexps
- allout-line-boundary-regexp
- extend)
- '(allout-encryption-ciphertext-rejection-regexps
- allout-bob-regexp
- extend))
-
- ;; Produce map from current version of allout-keybindings-list:
- (allout-setup-mode-map)
+ (allout-add-resumptions '(allout-encryption-ciphertext-rejection-regexps
+ allout-line-boundary-regexp
+ extend)
+ '(allout-encryption-ciphertext-rejection-regexps
+ allout-bob-regexp
+ extend))
+
+ (allout-compose-and-institute-keymap)
(produce-allout-mode-menubar-entries)
- ;; Include on minor-mode-map-alist, if not already there:
- (if (not (member '(allout-mode . allout-mode-map)
- minor-mode-map-alist))
- (setq minor-mode-map-alist
- (cons '(allout-mode . allout-mode-map)
- minor-mode-map-alist)))
-
(add-to-invisibility-spec '(allout . t))
(allout-add-resumptions '(line-move-ignore-invisible t))
(add-hook 'pre-command-hook 'allout-pre-command-business nil t)
(add-hook 'post-command-hook 'allout-post-command-business nil t)
- (add-hook 'before-change-functions 'allout-before-change-handler
- 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
nil t)
- (add-hook 'auto-save-hook 'allout-auto-save-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
;; custom func respects topic headline, maintains hanging-indents,
;; etc.)
- (if (and auto-fill-function (not allout-inhibit-auto-fill))
- ;; allout-auto-fill will use the stashed values and so forth.
- (allout-add-resumptions '(auto-fill-function allout-auto-fill)))
(allout-add-resumptions (list 'allout-former-auto-filler
auto-fill-function)
;; Register allout-auto-fill to be used if
@@ -2207,91 +2074,51 @@ OPEN: A TOPIC that is not CLOSED, though its OFFSPRING or BODY may be."
(list 'paragraph-separate
(concat paragraph-separate "\\|^\\("
allout-regexp "\\)")))
- (or (assq 'allout-mode minor-mode-alist)
- (setq minor-mode-alist
- (cons '(allout-mode " Allout") minor-mode-alist)))
+ (if (and auto-fill-function (not allout-inhibit-auto-fill))
+ ;; allout-auto-fill will use the stashed values and so forth.
+ (allout-add-resumptions '(auto-fill-function allout-auto-fill)))
(allout-setup-menubar)
- (if allout-layout
- (setq do-layout t))
-
- (setq allout-mode t)
- (run-hooks 'allout-mode-hook))
-
- ;; Reactivation:
- ((setq do-layout t)
- (allout-infer-body-reindent))
- ) ;; end of activation-mode cases.
-
- ;; Do auto layout if warranted:
- (let ((use-layout (if (listp allout-layout)
- allout-layout
- allout-default-layout)))
- (if (and do-layout
- allout-auto-activation
- use-layout
- (and (not (eq allout-auto-activation 'activate))
- (if (eq allout-auto-activation 'ask)
- (if (y-or-n-p (format "Expose %s with layout '%s'? "
- (buffer-name)
- use-layout))
- t
- (message "Skipped %s layout." (buffer-name))
- nil)
- t)))
- (save-excursion
- (message "Adjusting '%s' exposure..." (buffer-name))
- (goto-char 0)
- (allout-this-or-next-heading)
- (condition-case err
- (progn
- (apply 'allout-expose-topic (list use-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))))))
- allout-mode
- ) ; let*
- ) ; defun
-
-(defun allout-setup-mode-map ()
- "Establish allout-mode bindings."
- (setq-default allout-mode-map
- (produce-allout-mode-map
- (allout-mode-map-adjustments allout-keybindings-list)))
- (setq allout-mode-map
- (produce-allout-mode-map
- (allout-mode-map-adjustments allout-keybindings-list)))
- (substitute-key-definition 'beginning-of-line
- 'allout-beginning-of-line
- allout-mode-map global-map)
- (substitute-key-definition 'move-beginning-of-line
- 'allout-beginning-of-line
- allout-mode-map global-map)
- (substitute-key-definition 'end-of-line
- 'allout-end-of-line
- allout-mode-map global-map)
- (substitute-key-definition 'move-end-of-line
- 'allout-end-of-line
- allout-mode-map global-map)
- (fset 'allout-mode-map allout-mode-map))
-
-;; ensure that allout-mode-map has some setting even if allout-mode hasn't
-;; been invoked:
-(allout-setup-mode-map)
-
-;;;_ > allout-minor-mode
+ ;; Do auto layout if warranted:
+ (when (and allout-layout
+ allout-auto-activation
+ use-layout
+ (and (not (eq allout-auto-activation 'activate))
+ (if (eq allout-auto-activation 'ask)
+ (if (y-or-n-p (format "Expose %s with layout '%s'? "
+ (buffer-name)
+ use-layout))
+ t
+ (message "Skipped %s layout." (buffer-name))
+ nil)
+ t)))
+ (save-excursion
+ (message "Adjusting '%s' exposure..." (buffer-name))
+ (goto-char 0)
+ (allout-this-or-next-heading)
+ (condition-case err
+ (progn
+ (apply 'allout-expose-topic (list use-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))))
+ ) ; when allout-layout
+ ) ; if (allout-mode-p)
+ ) ; let (())
+ ) ; define-minor-mode
+;;;_ > allout-minor-mode alias
(defalias 'allout-minor-mode 'allout-mode)
-
;;;_ > allout-unload-function
(defun allout-unload-function ()
"Unload the allout outline library."
(save-current-buffer
(dolist (buffer (buffer-list))
(set-buffer buffer)
- (when allout-mode (allout-mode -1))))
+ (when (allout-mode-p) (allout-mode))))
;; continue standard unloading
nil)
@@ -2360,8 +2187,8 @@ internal functions use this feature cohesively bunch changes."
See `allout-overlay-interior-modification-handler' for details."
- (if (and (allout-mode-p) undo-in-progress (allout-hidden-p))
- (allout-show-to-offshoot))
+ (when (and (allout-mode-p) undo-in-progress (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.
@@ -3058,13 +2885,19 @@ of (before any) topics, in which case we return nil."
(allout-beginning-of-current-line)
(let ((bol-point (point)))
- (if (allout-goto-prefix-doublechecked)
- (if (<= (point) bol-point)
+ (when (allout-goto-prefix-doublechecked)
+ (if (<= (point) bol-point)
+ (progn
+ (setq bol-point (point))
+ (allout-beginning-of-current-line)
+ (if (not (= bol-point (point)))
+ (if (looking-at allout-regexp)
+ (allout-prefix-data)))
(if interactive
(allout-end-of-prefix)
- (point))
- (goto-char (point-min))
- nil))))
+ (point)))
+ (goto-char (point-min))
+ nil))))
;;;_ > allout-back-to-heading ()
(defalias 'allout-back-to-heading 'allout-back-to-current-heading)
;;;_ > allout-pre-next-prefix ()
@@ -3389,6 +3222,7 @@ Move to buffer limit in indicated direction if headings are exhausted."
(let* ((inhibit-field-text-motion t)
(backward (if (< arg 0) (setq arg (* -1 arg))))
(step (if backward -1 1))
+ (progress (allout-current-bullet-pos))
prev got)
(while (> arg 0)
@@ -3398,7 +3232,17 @@ Move to buffer limit in indicated direction if headings are exhausted."
;; Move, skipping over all concealed lines in one fell swoop:
(prog1 (condition-case nil (or (line-move step) t)
(error nil))
- (allout-beginning-of-current-line))
+ (allout-beginning-of-current-line)
+ ;; line-move can wind up on the same line if long.
+ ;; when moving forward, that would yield no-progress
+ (when (and (not backward)
+ (<= (point) progress))
+ ;; ensure progress by doing line-move from end-of-line:
+ (end-of-line)
+ (condition-case nil (or (line-move step) t)
+ (error nil))
+ (allout-beginning-of-current-line)
+ (setq progress (point))))
;; Deal with apparent header line:
(save-match-data
(if (not (looking-at allout-regexp))
@@ -3481,7 +3325,7 @@ When set, tells post-processing to reposition on topic bullet, and
then unset it. Set by `allout-pre-command-business' when implementing
hot-spot operation, where literal characters typed over a topic bullet
are mapped to the command of the corresponding control-key on the
-`allout-mode-map'.")
+`allout-mode-map-value'.")
(make-variable-buffer-local 'allout-post-goto-bullet)
;;;_ = allout-command-counter
(defvar allout-command-counter 0
@@ -3520,11 +3364,12 @@ coordinating with allout activity.")
Among other things, implements special behavior when the cursor is on the
topic bullet character.
-When the cursor is on the bullet character, self-insert characters are
-reinterpreted as the corresponding control-character in the
-`allout-mode-map'. The `allout-mode' `post-command-hook' insures that
-the cursor which has moved as a result of such reinterpretation is
-positioned on the bullet character of the destination topic.
+When the cursor is on the bullet character, self-insert
+characters are reinterpreted as the corresponding
+control-character in the `allout-mode-map-value'. The
+`allout-mode' `post-command-hook' insures that the cursor which
+has moved as a result of such reinterpretation is positioned on
+the bullet character of the destination topic.
The upshot is that you can get easy, single (ie, unmodified) key
outline maneuvering operations by positioning the cursor on the bullet
@@ -3551,9 +3396,6 @@ this-command accordingly.
Returns the qualifying command, if any, else nil."
(interactive)
(let* ((modified (event-modifiers last-command-event))
- (key-string (if (numberp last-command-event)
- (char-to-string
- (event-basic-type last-command-event))))
(key-num (cond ((numberp last-command-event) last-command-event)
;; for XEmacs character type:
((and (fboundp 'characterp)
@@ -3570,16 +3412,18 @@ Returns the qualifying command, if any, else nil."
(not modified)
(<= 33 key-num)
(setq mapped-binding
- (or (and (assoc key-string allout-keybindings-list)
- ;; translate literal membership on list:
- (cadr (assoc key-string allout-keybindings-list)))
- ;; translate as a keybinding:
- (key-binding (vconcat allout-command-prefix
- (vector
- (if (and (<= 97 key-num) ; "a"
- (>= 122 key-num)) ; "z"
- (- key-num 96) key-num)))
- t))))
+ (or
+ ;; try control-modified versions of keys:
+ (key-binding (vconcat allout-command-prefix
+ (vector
+ (if (and (<= 97 key-num) ; "a"
+ (>= 122 key-num)) ; "z"
+ (- key-num 96) key-num)))
+ t)
+ ;; try non-modified versions of keys:
+ (key-binding (vconcat allout-command-prefix
+ (vector key-num))
+ t))))
;; Qualified as an allout command -- do hot-spot operation.
(setq allout-post-goto-bullet t)
;; accept-defaults nil, or else we get allout-item-icon-key-handler.
@@ -3600,7 +3444,7 @@ See `allout-init' for setup instructions."
(if (and allout-auto-activation
(not (allout-mode-p))
allout-layout)
- (allout-mode t)))
+ (allout-mode)))
;;;_ - Topic Format Assessment
;;;_ > allout-solicit-alternate-bullet (depth &optional current-bullet)
@@ -4047,9 +3891,13 @@ Maintains outline hanging topic indentation if
(make-string (progn (allout-end-of-prefix)
(current-column))
?\ ))))))
- (use-auto-fill-function (or allout-outside-normal-auto-fill-function
- auto-fill-function
- 'do-auto-fill)))
+ (use-auto-fill-function
+ (if (and (eq allout-outside-normal-auto-fill-function
+ 'allout-auto-fill)
+ (eq auto-fill-function 'allout-auto-fill))
+ 'do-auto-fill
+ (or allout-outside-normal-auto-fill-function
+ auto-fill-function))))
(if (or allout-former-auto-filler allout-use-hanging-indents)
(funcall use-auto-fill-function)))))
;;;_ > allout-reindent-body (old-depth new-depth &optional number)
@@ -4914,9 +4762,7 @@ by pops to non-distinctive yanks. Bug..."
"Conceal text between FROM and TO if FLAG is non-nil, else reveal it.
Exposure-change hook `allout-exposure-change-hook' is run with the same
-arguments as this function, after the exposure changes are made. (The old
-`allout-view-change-hook' is being deprecated, and eventually will not be
-invoked.)"
+arguments as this function, after the exposure changes are made."
;; We use outline invisibility spec.
(remove-overlays from to 'category 'allout-exposure-category)
@@ -4930,7 +4776,6 @@ invoked.)"
;; as of 2008-02-27, xemacs lacks modification-hooks
(overlay-put o (pop props) (pop props))
(error nil)))))))
- (run-hooks 'allout-view-change-hook)
(run-hook-with-args 'allout-exposure-change-hook from to flag))
;;;_ > allout-flag-current-subtree (flag)
(defun allout-flag-current-subtree (flag)
@@ -5132,7 +4977,8 @@ default, they are treated as being uncollapsed."
(and
;; Is the topic all on one line (allowing for trailing blank line)?
(>= (progn (allout-back-to-current-heading)
- (move-end-of-line 1)
+ (let ((inhibit-field-text-motion t))
+ (move-end-of-line 1))
(point))
(allout-end-of-current-subtree (not (looking-at "\n\n"))))
@@ -5999,31 +5845,39 @@ With repeat count, copy the exposed portions of entire buffer."
(goto-char start-pt)))
;;;_ #8 Encryption
-;;;_ > allout-toggle-current-subtree-encryption (&optional fetch-pass)
-(defun allout-toggle-current-subtree-encryption (&optional fetch-pass)
- "Encrypt clear or decrypt encoded text of visibly-containing topic's contents.
-
-Optional FETCH-PASS universal argument provokes key-pair encryption with
-single universal argument. With doubled universal argument (value = 16),
-it forces prompting for the passphrase regardless of availability from the
-passphrase cache. With no universal argument, the appropriate passphrase
-is obtained from the cache, if available, else from the user.
-
-Only GnuPG encryption is supported.
-
-\*NOTE WELL* that the encrypted text must be ascii-armored. For gnupg
-encryption, include the option ``armor'' in your ~/.gnupg/gpg.conf file.
-
-Both symmetric-key and key-pair encryption is implemented. Symmetric is
-the default, use a single (x4) universal argument for keypair mode.
-
-Encrypted topic's bullet is set to a `~' to signal that the contents of the
-topic (body and subtopics, but not heading) is pending encryption or
-encrypted. `*' asterisk immediately after the bullet signals that the body
-is encrypted, its' absence means the topic is meant to be encrypted but is
-not. When a file with topics pending encryption is saved, topics pending
-encryption are encrypted. See allout-encrypt-unencrypted-on-saves for
-auto-encryption specifics.
+;;;_ > allout-toggle-current-subtree-encryption (&optional keymode-cue)
+(defun allout-toggle-current-subtree-encryption (&optional keymode-cue)
+ "Encrypt clear or decrypt encoded topic text.
+
+Allout uses emacs 'epg' libary to perform encryption. Symmetric
+and keypair encryption are supported. All encryption is ascii
+armored.
+
+Entry encryption defaults to symmetric key mode unless keypair
+recipients are associated with the file \(see
+`epa-file-encrypt-to') or the function is invoked with a
+\(KEYMODE-CUE) universal argument greater than 1.
+
+When encrypting, KEYMODE-CUE universal argument greater than 1
+causes prompting for recipients for public-key keypair
+encryption. Selecting no recipients results in symmetric key
+encryption.
+
+Further, encrypting with a KEYMODE-CUE universal argument greater
+than 4 - eg, preceded by a doubled Ctrl-U - causes association of
+the specified recipients with the file, replacing those currently
+associated with it. This can be used to deassociate any
+recipients with the file, by selecting no recipients in the
+dialog.
+
+Encrypted topic's bullets are set to a `~' to signal that the
+contents of the topic (body and subtopics, but not heading) is
+pending encryption or encrypted. `*' asterisk immediately after
+the bullet signals that the body is encrypted, its absence means
+the topic is meant to be encrypted but is not currently. When a
+file with topics pending encryption is saved, topics pending
+encryption are encrypted. See allout-encrypt-unencrypted-on-saves
+for auto-encryption specifics.
\*NOTE WELL* that automatic encryption that happens during saves will
default to symmetric encryption -- you must deliberately (re)encrypt key-pair
@@ -6031,59 +5885,35 @@ encrypted topics if you want them to continue to use the key-pair cipher.
Level-one topics, with prefix consisting solely of an `*' asterisk, cannot be
encrypted. If you want to encrypt the contents of a top-level topic, use
-\\[allout-shift-in] to increase its depth.
-
- Passphrase Caching
-
-The encryption passphrase is solicited if not currently available in the
-passphrase cache from a recent encryption action.
-
-The solicited passphrase is retained for reuse in a cache, if enabled. See
-`pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' for details.
-
- Symmetric Passphrase Hinting and Verification
-
-If the file previously had no associated passphrase, or had a different
-passphrase than specified, the user is prompted to repeat the new one for
-corroboration. A random string encrypted by the new passphrase is set on
-the buffer-specific variable `allout-passphrase-verifier-string', for
-confirmation of the passphrase when next obtained, before encrypting or
-decrypting anything with it. This helps avoid mistakenly shifting between
-keys.
-
-If allout customization var `allout-passphrase-verifier-handling' is
-non-nil, an entry for `allout-passphrase-verifier-string' and its value is
-added to an Emacs 'local variables' section at the end of the file, which
-is created if necessary. That setting is for retention of the passphrase
-verifier across Emacs sessions.
-
-Similarly, `allout-passphrase-hint-string' stores a user-provided reminder
-about their passphrase, and `allout-passphrase-hint-handling' specifies
-when the hint is presented, or if passphrase hints are disabled. If
-enabled (see the `allout-passphrase-hint-handling' docstring for details),
-the hint string is stored in the local-variables section of the file, and
-solicited whenever the passphrase is changed."
+\\[allout-shift-in] to increase its depth."
(interactive "P")
(save-excursion
(allout-back-to-current-heading)
- (allout-toggle-subtree-encryption fetch-pass)
- )
- )
-;;;_ > allout-toggle-subtree-encryption (&optional fetch-pass)
-(defun allout-toggle-subtree-encryption (&optional fetch-pass)
+ (allout-toggle-subtree-encryption keymode-cue)))
+;;;_ > allout-toggle-subtree-encryption (&optional keymode-cue)
+(defun allout-toggle-subtree-encryption (&optional keymode-cue)
"Encrypt clear text or decrypt encoded topic contents (body and subtopics.)
-Optional FETCH-PASS universal argument provokes key-pair encryption with
-single universal argument. With doubled universal argument (value = 16),
-it forces prompting for the passphrase regardless of availability from the
-passphrase cache. With no universal argument, the appropriate passphrase
-is obtained from the cache, if available, else from the user.
+Entry encryption defaults to symmetric key mode unless keypair
+recipients are associated with the file \(see
+`epa-file-encrypt-to') or the function is invoked with a
+\(KEYMODE-CUE) universal argument greater than 1.
+
+When encrypting, KEYMODE-CUE universal argument greater than 1
+causes prompting for recipients for public-key keypair
+encryption. Selecting no recipients results in symmetric key
+encryption.
-Currently only GnuPG encryption is supported, and integration
-with gpg-agent is not yet implemented.
+Further, encrypting with a KEYMODE-CUE universal argument greater
+than 4 - eg, preceded by a doubled Ctrl-U - causes association of
+the specified recipients with the file, replacing those currently
+associated with it. This can be used to deassociate any
+recipients with the file, by selecting no recipients in the
+dialog.
-\**NOTE WELL** that the encrypted text must be ascii-armored. For gnupg
-encryption, include the option ``armor'' in your ~/.gnupg/gpg.conf file.
+Encryption and decryption uses the emacs epg library.
+
+Encrypted text will be ascii-armored.
See `allout-toggle-current-subtree-encryption' for more details."
@@ -6121,16 +5951,6 @@ See `allout-toggle-current-subtree-encryption' for more details."
(if was-encrypted "de" "en"))
nil))
;; Assess key parameters:
- (key-info (or
- ;; detect the type by which it is already encrypted
- (and was-encrypted
- (allout-encrypted-key-info subject-text))
- (and (member fetch-pass '(4 (4)))
- '(keypair nil))
- '(symmetric nil)))
- (for-key-type (car key-info))
- (for-key-identity (cadr key-info))
- (fetch-pass (and fetch-pass (member fetch-pass '(16 (16)))))
(was-coding-system buffer-file-coding-system))
(when (not was-encrypted)
@@ -6156,8 +5976,7 @@ See `allout-toggle-current-subtree-encryption' for more details."
(setq result-text
(allout-encrypt-string subject-text was-encrypted
- (current-buffer)
- for-key-type for-key-identity fetch-pass))
+ (current-buffer) keymode-cue))
;; Replace the subtree with the processed product.
(allout-unprotected
@@ -6188,335 +6007,173 @@ See `allout-toggle-current-subtree-encryption' for more details."
(insert "*"))))
(run-hook-with-args 'allout-structure-added-hook
bullet-pos subtree-end))))
-;;;_ > allout-encrypt-string (text decrypt allout-buffer key-type for-key
-;;; fetch-pass &optional retried verifying
-;;; passphrase)
-(defun allout-encrypt-string (text decrypt allout-buffer key-type for-key
- fetch-pass &optional retried rejected
- verifying passphrase)
+;;;_ > allout-encrypt-string (text decrypt allout-buffer keymode-cue
+;;; &optional rejected)
+(defun allout-encrypt-string (text decrypt allout-buffer keymode-cue
+ &optional rejected)
"Encrypt or decrypt message TEXT.
-If DECRYPT is true (default false), then decrypt instead of encrypt.
+Returns the resulting string, or nil if the transformation fails.
-FETCH-PASS (default false) forces fresh prompting for the passphrase.
+If DECRYPT is true (default false), then decrypt instead of encrypt.
-KEY-TYPE, either `symmetric' or `keypair', specifies which type
-of cypher to use.
+ALLOUT-BUFFER identifies the buffer containing the text.
-FOR-KEY is human readable identification of the first of the user's
-eligible secret keys a keypair decryption targets, or else nil.
+Entry encryption defaults to symmetric key mode unless keypair
+recipients are associated with the file \(see
+`epa-file-encrypt-to') or the function is invoked with a
+\(KEYMODE-CUE) universal argument greater than 1.
-Optional RETRIED is for internal use -- conveys the number of failed keys
-that have been solicited in sequence leading to this current call.
+When encrypting, KEYMODE-CUE universal argument greater than 1
+causes prompting for recipients for public-key keypair
+encryption. Selecting no recipients results in symmetric key
+encryption.
-Optional PASSPHRASE enables explicit delivery of the decryption passphrase,
-for verification purposes.
+Further, encrypting with a KEYMODE-CUE universal argument greater
+than 4 - eg, preceded by a doubled Ctrl-U - causes association of
+the specified recipients with the file, replacing those currently
+associated with it. This can be used to deassociate any
+recipients with the file, by selecting no recipients in the
+dialog.
-Optional REJECTED is for internal use -- conveys the number of
+Optional REJECTED is for internal use, to convey the number of
rejections due to matches against
`allout-encryption-ciphertext-rejection-regexps', as limited by
`allout-encryption-ciphertext-rejection-ceiling'.
-Returns the resulting string, or nil if the transformation fails."
-
- (require 'pgg)
-
- (if (not (fboundp 'pgg-encrypt-symmetric))
- (error "Allout encryption depends on a newer version of pgg"))
-
- (let* ((scheme (upcase
- (format "%s" (or pgg-scheme pgg-default-scheme "GPG"))))
- (for-key (and (equal key-type 'keypair)
- (or for-key
- (split-string (read-string
- (format "%s message recipients: "
- scheme))
- "[ \t,]+"))))
- (target-prompt-id (if (equal key-type 'keypair)
- (if (= (length for-key) 1)
- (car for-key) for-key)
- (buffer-name allout-buffer)))
- (target-cache-id (format "%s-%s"
- key-type
- (if (equal key-type 'keypair)
- target-prompt-id
- (or (buffer-file-name allout-buffer)
- target-prompt-id))))
+NOTE: A few GnuPG v2 versions improperly preserve incorrect
+symmetric decryption keys, preventing entry of the correct key on
+subsequent decryption attempts until the cache times-out. That
+can take several minutes. \(Decryption of other entries is not
+affected.) Upgrade your EasyPG version, if you can, and you can
+deliberately clear your gpg-agent's cache by sending it a '-HUP'
+signal."
+
+ (require 'epg)
+ (require 'epa)
+
+ (let* ((epg-context (let* ((context (epg-make-context nil t)))
+ (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
- enable-multibyte-characters))
- (strip-plaintext-regexps
- (if (not decrypt)
- (allout-get-configvar-values
- 'allout-encryption-plaintext-sanitization-regexps)))
- (reject-ciphertext-regexps
- (if (not decrypt)
- (allout-get-configvar-values
- 'allout-encryption-ciphertext-rejection-regexps)))
+ enable-multibyte-characters))
+ ;; "sanitization" avoids encryption results that are outline structure.
+ (sani-regexps 'allout-encryption-plaintext-sanitization-regexps)
+ (strip-plaintext-regexps (if (not decrypt)
+ (allout-get-configvar-values
+ sani-regexps)))
+ (rejection-regexps 'allout-encryption-ciphertext-rejection-regexps)
+ (reject-ciphertext-regexps (if (not decrypt)
+ (allout-get-configvar-values
+ rejection-regexps)))
(rejected (or rejected 0))
(rejections-left (- allout-encryption-ciphertext-rejection-ceiling
rejected))
- result-text status
+ (keypair-mode (cond (decrypt 'decrypting)
+ ((<= (prefix-numeric-value keymode-cue) 1)
+ 'default)
+ ((<= (prefix-numeric-value keymode-cue) 4)
+ 'prompt)
+ ((> (prefix-numeric-value keymode-cue) 4)
+ 'prompt-save)))
+ (keypair-message (concat "Select encryption recipients.\n"
+ "Symmetric encryption is done if no"
+ " recipients are selected. "))
+ (encrypt-to (and (boundp 'epa-file-encrypt-to) epa-file-encrypt-to))
+ recipients
+ massaged-text
+ result-text
)
- (if (and fetch-pass (not passphrase))
- ;; Force later fetch by evicting passphrase from the cache.
- (pgg-remove-passphrase-from-cache target-cache-id t))
-
- (catch 'encryption-failed
-
- ;; We handle only symmetric-key passphrase caching.
- (if (and (not passphrase)
- (not (equal key-type 'keypair)))
- (setq passphrase (allout-obtain-passphrase for-key
- target-cache-id
- target-prompt-id
- key-type
- allout-buffer
- retried fetch-pass)))
-
- (with-temp-buffer
-
- (insert text)
-
- ;; convey the text characteristics of the original buffer:
- (allout-set-buffer-multibyte multibyte)
- (when encoding
- (set-buffer-file-coding-system encoding)
- (if (not decrypt)
- (encode-coding-region (point-min) (point-max) encoding)))
-
- (when (and strip-plaintext-regexps (not decrypt))
- (dolist (re strip-plaintext-regexps)
- (let ((re (if (listp re) (car re) re))
- (replacement (if (listp re) (cadr re) "")))
- (goto-char (point-min))
- (save-match-data
- (while (re-search-forward re nil t)
- (replace-match replacement nil nil))))))
-
- (cond
-
- ;; symmetric:
- ((equal key-type 'symmetric)
- (setq status
- (if decrypt
-
- (pgg-decrypt (point-min) (point-max) passphrase)
-
- (pgg-encrypt-symmetric (point-min) (point-max)
- passphrase)))
-
- (if status
- (pgg-situate-output (point-min) (point-max))
- ;; failed -- handle passphrase caching
- (if verifying
- (throw 'encryption-failed nil)
- (pgg-remove-passphrase-from-cache target-cache-id t)
- (error "Symmetric-cipher %scryption failed -- %s"
- (if decrypt "de" "en")
- "try again with different passphrase"))))
-
- ;; encrypt `keypair':
- ((not decrypt)
-
- (setq status
-
- (pgg-encrypt for-key
- nil (point-min) (point-max) passphrase))
-
- (if status
- (pgg-situate-output (point-min) (point-max))
- (error (pgg-remove-passphrase-from-cache target-cache-id t)
- (error "encryption failed"))))
-
- ;; decrypt `keypair':
- (t
-
- (setq status
- (pgg-decrypt (point-min) (point-max) passphrase))
-
- (if status
- (pgg-situate-output (point-min) (point-max))
- (error (pgg-remove-passphrase-from-cache target-cache-id t)
- (error "decryption failed")))))
-
- (setq result-text
- (buffer-substring-no-properties
- 1 (- (point-max) (if decrypt 0 1))))
- )
-
- ;; validate result -- non-empty
- (cond ((not result-text)
- (if verifying
- nil
- ;; transform was fruitless, retry w/new passphrase.
- (pgg-remove-passphrase-from-cache target-cache-id t)
- (allout-encrypt-string text decrypt allout-buffer
- key-type for-key nil
- (if retried (1+ retried) 1)
- rejected verifying nil)))
-
- ;; Retry (within limit) if ciphertext contains rejections:
- ((and (not decrypt)
- ;; Check for disqualification of this ciphertext:
- (let ((regexps reject-ciphertext-regexps)
- reject-it)
- (while (and regexps (not reject-it))
- (setq reject-it (string-match (car regexps)
- result-text))
- (pop regexps))
- reject-it))
- (setq rejections-left (1- rejections-left))
- (if (<= rejections-left 0)
- (error (concat "Ciphertext rejected too many times"
- " (%s), per `%s'")
- allout-encryption-ciphertext-rejection-ceiling
- 'allout-encryption-ciphertext-rejection-regexps)
- (allout-encrypt-string text decrypt allout-buffer
- key-type for-key nil
- retried (1+ rejected)
- verifying passphrase)))
- ;; Barf if encryption yields extraordinary control chars:
- ((and (not decrypt)
- (string-match "[\C-a\C-k\C-o-\C-z\C-@]"
- result-text))
- (error (concat "Encryption produced non-armored text, which"
- "conflicts with allout mode -- reconfigure!")))
-
- ;; valid result and just verifying or non-symmetric:
- ((or verifying (not (equal key-type 'symmetric)))
- (if (or verifying decrypt)
- (pgg-add-passphrase-to-cache target-cache-id
- passphrase t))
- result-text)
-
- ;; valid result and regular symmetric -- "register"
- ;; passphrase with mnemonic aids/cache.
- (t
- (set-buffer allout-buffer)
- (if passphrase
- (pgg-add-passphrase-to-cache target-cache-id
- passphrase t))
- (allout-update-passphrase-mnemonic-aids for-key passphrase
- allout-buffer)
- result-text)
- )
- )
- )
- )
-;;;_ > allout-obtain-passphrase (for-key cache-id prompt-id key-type
-;;; allout-buffer retried fetch-pass)
-(defun allout-obtain-passphrase (for-key cache-id prompt-id key-type
- allout-buffer retried fetch-pass)
- "Obtain passphrase for a key from the cache or else from the user.
-
-When obtaining from the user, symmetric-cipher passphrases are verified
-against either, if available and enabled, a random string that was
-encrypted against the passphrase, or else against repeated entry by the
-user for corroboration.
-
-FOR-KEY is the key for which the passphrase is being obtained.
-
-CACHE-ID is the cache id of the key for the passphrase.
-
-PROMPT-ID is the id for use when prompting the user.
-
-KEY-TYPE is either `symmetric' or `keypair'.
-
-ALLOUT-BUFFER is the buffer containing the entry being en/decrypted.
-
-RETRIED is the number of this attempt to obtain this passphrase.
-
-FETCH-PASS causes the passphrase to be solicited from the user, regardless
-of the availability of a cached copy."
-
- (if (not (equal key-type 'symmetric))
- ;; do regular passphrase read on non-symmetric passphrase:
- (pgg-read-passphrase (format "%s passphrase%s: "
- (upcase (format "%s" (or pgg-scheme
- pgg-default-scheme
- "GPG")))
- (if prompt-id
- (format " for %s" prompt-id)
- ""))
- cache-id t)
-
- ;; Symmetric hereon:
-
- (with-current-buffer allout-buffer
- (let* ((hint (if (and (not (string= allout-passphrase-hint-string ""))
- (or (equal allout-passphrase-hint-handling 'always)
- (and (equal allout-passphrase-hint-handling
- 'needed)
- retried)))
- (format " [%s]" allout-passphrase-hint-string)
- ""))
- (retry-message (if retried (format " (%s retry)" retried) ""))
- (prompt-sans-hint (format "'%s' symmetric passphrase%s: "
- prompt-id retry-message))
- (full-prompt (format "'%s' symmetric passphrase%s%s: "
- prompt-id hint retry-message))
- (prompt full-prompt)
- (verifier-string (allout-get-encryption-passphrase-verifier))
-
- (cached (and (not fetch-pass)
- (pgg-read-passphrase-from-cache cache-id t)))
- (got-pass (or cached
- (pgg-read-passphrase full-prompt cache-id t)))
- confirmation)
-
- (if (not got-pass)
- nil
+ ;; Massage the subject text for encoding and filtering.
+ (with-temp-buffer
+ (insert text)
+ ;; convey the text characteristics of the original buffer:
+ (allout-set-buffer-multibyte multibyte)
+ (when encoding
+ (set-buffer-file-coding-system encoding)
+ (if (not decrypt)
+ (encode-coding-region (point-min) (point-max) encoding)))
+
+ ;; remove sanitization regexps matches before encrypting:
+ (when (and strip-plaintext-regexps (not decrypt))
+ (dolist (re strip-plaintext-regexps)
+ (let ((re (if (listp re) (car re) re))
+ (replacement (if (listp re) (cadr re) "")))
+ (goto-char (point-min))
+ (save-match-data
+ (while (re-search-forward re nil t)
+ (replace-match replacement nil nil))))))
+ (setq massaged-text (buffer-substring-no-properties (point-min)
+ (point-max))))
+ ;; determine key mode and, if keypair, recipients:
+ (setq recipients
+ (case keypair-mode
+
+ (decrypting nil)
+
+ (default (if encrypt-to (epg-list-keys epg-context encrypt-to)))
+
+ ((prompt prompt-save)
+ (save-window-excursion
+ (epa-select-keys epg-context keypair-message)))))
+
+ (setq result-text
+ (if decrypt
+ (epg-decrypt-string epg-context
+ (encode-coding-string massaged-text
+ (or encoding 'utf-8)))
+ (replace-regexp-in-string "\n$" ""
+ (epg-encrypt-string epg-context
+ (encode-coding-string massaged-text
+ (or encoding 'utf-8))
+ recipients))))
+
+ ;; validate result -- non-empty
+ (if (not result-text)
+ (error "%scryption failed." (if decrypt "De" "En")))
+
+
+ (when (eq keypair-mode 'prompt-save)
+ ;; set epa-file-encrypt-to in the buffer:
+ (setq epa-file-encrypt-to (mapcar (lambda (key)
+ (epg-user-id-string
+ (car (epg-key-user-id-list key))))
+ recipients))
+ ;; change the file variable:
+ (allout-adjust-file-variable "epa-file-encrypt-to" epa-file-encrypt-to))
- ;; Duplicate our handle on the passphrase so it's not clobbered by
- ;; deactivate-passwd memory clearing:
- (setq got-pass (copy-sequence got-pass))
-
- (cond (verifier-string
- (save-window-excursion
- (if (allout-encrypt-string verifier-string 'decrypt
- allout-buffer 'symmetric
- for-key nil 0 0 'verifying
- (copy-sequence got-pass))
- (setq confirmation (format "%s" got-pass))))
-
- (if (and (not confirmation)
- (if (yes-or-no-p
- (concat "Passphrase differs from established"
- " -- use new one instead? "))
- ;; deactivate password for subsequent
- ;; confirmation:
- (progn
- (pgg-remove-passphrase-from-cache cache-id t)
- (setq prompt prompt-sans-hint)
- nil)
- t))
- (progn (pgg-remove-passphrase-from-cache cache-id t)
- (error "Wrong passphrase"))))
- ;; No verifier string -- force confirmation by repetition of
- ;; (new) passphrase:
- ((or fetch-pass (not cached))
- (pgg-remove-passphrase-from-cache cache-id t))))
- ;; confirmation vs new input -- doing pgg-read-passphrase will do the
- ;; right thing, in either case:
- (if (not confirmation)
- (setq confirmation
- (pgg-read-passphrase (concat prompt
- " ... confirm spelling: ")
- cache-id t)))
- (prog1
- (if (equal got-pass confirmation)
- confirmation
- (if (yes-or-no-p (concat "spelling of original and"
- " confirmation differ -- retry? "))
- (progn (setq retried (if retried (1+ retried) 1))
- (pgg-remove-passphrase-from-cache cache-id t)
- ;; recurse to this routine:
- (pgg-read-passphrase prompt-sans-hint cache-id t))
- (pgg-remove-passphrase-from-cache cache-id t)
- (error "Confirmation failed"))))))))
+ (cond
+ ;; Retry (within limit) if ciphertext contains rejections:
+ ((and (not decrypt)
+ ;; Check for disqualification of this ciphertext:
+ (let ((regexps reject-ciphertext-regexps)
+ reject-it)
+ (while (and regexps (not reject-it))
+ (setq reject-it (string-match (car regexps) result-text))
+ (pop regexps))
+ reject-it))
+ (setq rejections-left (1- rejections-left))
+ (if (<= rejections-left 0)
+ (error (concat "Ciphertext rejected too many times"
+ " (%s), per `%s'")
+ allout-encryption-ciphertext-rejection-ceiling
+ 'allout-encryption-ciphertext-rejection-regexps)
+ ;; try again (gpg-agent may have the key cached):
+ (allout-encrypt-string text decrypt allout-buffer keypair-mode
+ (1+ rejected))))
+
+ ;; Barf if encryption yields extraordinary control chars:
+ ((and (not decrypt)
+ (string-match "[\C-a\C-k\C-o-\C-z\C-@]"
+ result-text))
+ (error (concat "Encryption produced non-armored text, which"
+ "conflicts with allout mode -- reconfigure!")))
+
+ (t result-text))))
;;;_ > allout-encrypted-topic-p ()
(defun allout-encrypted-topic-p ()
"True if the current topic is encryptable and encrypted."
@@ -6527,128 +6184,6 @@ of the availability of a cached copy."
(save-match-data (looking-at "\\*")))
)
)
-;;;_ > allout-encrypted-key-info (text)
-;; XXX gpg-specific, alas
-(defun allout-encrypted-key-info (text)
- "Return a pair of the key type and identity of a recipient's secret key.
-
-The key type is one of `symmetric' or `keypair'.
-
-If `keypair', and some of the user's secret keys are among those for which
-the message was encoded, return the identity of the first. Otherwise,
-return nil for the second item of the pair.
-
-An error is raised if the text is not encrypted."
- (require 'pgg-parse)
- (save-excursion
- (with-temp-buffer
- (insert text)
- (let* ((parsed-armor (pgg-parse-armor-region (point-min) (point-max)))
- (type (if (pgg-gpg-symmetric-key-p parsed-armor)
- 'symmetric
- 'keypair))
- secret-keys first-secret-key for-key-owner)
- (if (equal type 'keypair)
- (setq secret-keys (pgg-gpg-lookup-all-secret-keys)
- first-secret-key (pgg-gpg-select-matching-key parsed-armor
- secret-keys)
- for-key-owner (and first-secret-key
- (pgg-gpg-lookup-key-owner
- first-secret-key))))
- (list type (pgg-gpg-key-id-from-key-owner for-key-owner))
- )
- )
- )
- )
-;;;_ > allout-create-encryption-passphrase-verifier (passphrase)
-(defun allout-create-encryption-passphrase-verifier (passphrase)
- "Encrypt random message for later validation of symmetric key's passphrase."
- ;; use 20 random ascii characters, across the entire ascii range.
- (random t)
- (let ((spew (make-string 20 ?\0)))
- (dotimes (i (length spew))
- (aset spew i (1+ (random 254))))
- (allout-encrypt-string spew nil (current-buffer) 'symmetric
- nil nil 0 0 passphrase))
- )
-;;;_ > allout-update-passphrase-mnemonic-aids (for-key passphrase
-;;; outline-buffer)
-(defun allout-update-passphrase-mnemonic-aids (for-key passphrase
- outline-buffer)
- "Update passphrase verifier and hint strings if necessary.
-
-See `allout-passphrase-verifier-string' and `allout-passphrase-hint-string'
-settings.
-
-PASSPHRASE is the passphrase being mnemonicized.
-
-OUTLINE-BUFFER is the buffer of the outline being adjusted.
-
-These are used to help the user keep track of the passphrase they use for
-symmetric encryption in the file.
-
-Behavior is governed by `allout-passphrase-verifier-handling',
-`allout-passphrase-hint-handling', and also, controlling whether the values
-are preserved on Emacs local file variables,
-`allout-enable-file-variable-adjustment'."
-
- ;; If passphrase doesn't agree with current verifier:
- ;; - adjust the verifier
- ;; - if passphrase hint handling is enabled, adjust the passphrase hint
- ;; - if file var settings are enabled, adjust the file vars
-
- (let* ((new-verifier-needed (not (allout-verify-passphrase
- for-key passphrase outline-buffer)))
- (new-verifier-string
- (if new-verifier-needed
- ;; Collapse to a single line and enclose in string quotes:
- (subst-char-in-string
- ?\n ?\C-a (allout-create-encryption-passphrase-verifier
- passphrase))))
- new-hint)
- (when new-verifier-string
- ;; do the passphrase hint first, since it's interactive
- (when (and allout-passphrase-hint-handling
- (not (equal allout-passphrase-hint-handling 'disabled)))
- (setq new-hint
- (read-from-minibuffer "Passphrase hint to jog your memory: "
- allout-passphrase-hint-string))
- (when (not (string= new-hint allout-passphrase-hint-string))
- (setq allout-passphrase-hint-string new-hint)
- (allout-adjust-file-variable "allout-passphrase-hint-string"
- allout-passphrase-hint-string)))
- (when allout-passphrase-verifier-handling
- (setq allout-passphrase-verifier-string new-verifier-string)
- (allout-adjust-file-variable "allout-passphrase-verifier-string"
- allout-passphrase-verifier-string))
- )
- )
- )
-;;;_ > allout-get-encryption-passphrase-verifier ()
-(defun allout-get-encryption-passphrase-verifier ()
- "Return text of the encrypt passphrase verifier, unmassaged, or nil if none.
-
-Derived from value of `allout-passphrase-verifier-string'."
-
- (let ((verifier-string (and (boundp 'allout-passphrase-verifier-string)
- allout-passphrase-verifier-string)))
- (if verifier-string
- ;; Return it uncollapsed
- (subst-char-in-string ?\C-a ?\n verifier-string))
- )
- )
-;;;_ > allout-verify-passphrase (key passphrase allout-buffer)
-(defun allout-verify-passphrase (key passphrase allout-buffer)
- "True if passphrase successfully decrypts verifier, nil otherwise.
-
-\"Otherwise\" includes absence of passphrase verifier."
- (with-current-buffer allout-buffer
- (and (boundp 'allout-passphrase-verifier-string)
- allout-passphrase-verifier-string
- (allout-encrypt-string (allout-get-encryption-passphrase-verifier)
- 'decrypt allout-buffer 'symmetric
- key nil 0 0 'verifying passphrase)
- t)))
;;;_ > allout-next-topic-pending-encryption (&optional except-mark)
(defun allout-next-topic-pending-encryption (&optional except-mark)
"Return the point of the next topic pending encryption, or nil if none.
@@ -6772,7 +6307,8 @@ setup for auto-startup."
(interactive "P")
- (allout-mode t)
+ (if (allout-mode-p) (allout-mode)) ; deactivate so we can re-activate...
+ (allout-mode)
(save-excursion
(goto-char (point-min))
@@ -7176,13 +6712,13 @@ To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
;; No docstring because xemacs defalias doesn't support it.
)
;;;_ > allout-set-buffer-multibyte
-;; define as alias first, so byte compiler is happy.
-(defalias 'allout-set-buffer-multibyte 'set-buffer-multibyte)
-;; then supplant with definition if underlying alias absent.
-(if (not (fboundp 'set-buffer-multibyte))
- (defun allout-set-buffer-multibyte (is-multibyte)
- (setq enable-multibyte-characters is-multibyte))
- )
+(if (fboundp 'set-buffer-multibyte)
+ (defalias 'allout-set-buffer-multibyte 'set-buffer-multibyte)
+ (with-no-warnings
+ ;; this definition is used only in older or alternative emacs, where
+ ;; the setting is our only recourse.
+ (defun allout-set-buffer-multibyte (is-multibyte)
+ (set enable-multibyte-characters is-multibyte))))
;;;_ > allout-select-safe-coding-system
(defalias 'allout-select-safe-coding-system
(if (fboundp 'select-safe-coding-system)